<p>N A has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/16226">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">func_sayfiles: Retrieve say file names<br><br>Up until now, all of the logic used to translate<br>arguments to the Say applications has been<br>directly coupled to playback, preventing other<br>modules from using this logic.<br><br>This refactors code in say.c and adds a SAYFILES<br>function that can be used to retrieve the file<br>names that would be played. These can then be<br>used in other applications or for other purposes.<br><br>ASTERISK-29531<br><br>Change-Id: If9718c89353b8e153d84add3cc4637b79585db19<br>---<br>A doc/CHANGES-staging/say.txt<br>A funcs/func_sayfiles.c<br>M include/asterisk/say.h<br>M main/say.c<br>4 files changed, 239 insertions(+), 33 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/26/16226/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/doc/CHANGES-staging/say.txt b/doc/CHANGES-staging/say.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..7b8e64d</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/say.txt</span><br><span>@@ -0,0 +1,5 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: say.c</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Refactors some code in say.c so that other Asterisk</span><br><span style="color: hsl(120, 100%, 40%);">+modules can use the filename logic independently</span><br><span style="color: hsl(120, 100%, 40%);">+of playback.</span><br><span>diff --git a/funcs/func_sayfiles.c b/funcs/func_sayfiles.c</span><br><span>new file mode 100644</span><br><span>index 0000000..934265f</span><br><span>--- /dev/null</span><br><span>+++ b/funcs/func_sayfiles.c</span><br><span>@@ -0,0 +1,139 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Asterisk -- An open source telephony toolkit.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2021, Naveen Albert <asterisk@phreaknet.org></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * See http://www.asterisk.org for more information about</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Asterisk project. Please do not directly contact</span><br><span style="color: hsl(120, 100%, 40%);">+ * any of the maintainers of this project for assistance;</span><br><span style="color: hsl(120, 100%, 40%);">+ * the project provides a web site, mailing lists and IRC</span><br><span style="color: hsl(120, 100%, 40%);">+ * channels for your use.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software, distributed under the terms of</span><br><span style="color: hsl(120, 100%, 40%);">+ * the GNU General Public License Version 2. See the LICENSE file</span><br><span style="color: hsl(120, 100%, 40%);">+ * at the top of the source tree.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \file</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Returns files played by Say applications</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \author Naveen Albert <asterisk@phreaknet.org></span><br><span style="color: hsl(120, 100%, 40%);">+ * \ingroup functions</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*** MODULEINFO</span><br><span style="color: hsl(120, 100%, 40%);">+ <support_level>extended</support_level></span><br><span style="color: hsl(120, 100%, 40%);">+ ***/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/pbx.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/file.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/channel.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/say.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/lock.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/localtime.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/utils.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/app.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/test.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/module.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*** DOCUMENTATION</span><br><span style="color: hsl(120, 100%, 40%);">+ <function name="SAYFILES" language="en_US"></span><br><span style="color: hsl(120, 100%, 40%);">+ <synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+ Returns the file names that would be played by the Say applications (e.g. SayAlpha, SayDigits).</span><br><span style="color: hsl(120, 100%, 40%);">+ </synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+ <syntax></span><br><span style="color: hsl(120, 100%, 40%);">+ <parameter name="value" required="true"></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>The value to be translated to filenames.</para></span><br><span style="color: hsl(120, 100%, 40%);">+ </parameter></span><br><span style="color: hsl(120, 100%, 40%);">+ <parameter name="value"></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>Say application type.</para></span><br><span style="color: hsl(120, 100%, 40%);">+ <enumlist></span><br><span style="color: hsl(120, 100%, 40%);">+ <enum name="alpha"></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>Files played by SayAlpha(). Default if none is specified.</para></span><br><span style="color: hsl(120, 100%, 40%);">+ </enum></span><br><span style="color: hsl(120, 100%, 40%);">+ <enum name="phonetic"></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>Files played by SayPhonetic().</para></span><br><span style="color: hsl(120, 100%, 40%);">+ </enum></span><br><span style="color: hsl(120, 100%, 40%);">+ <enum name="digits"></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>Files played by SayDigits().</para></span><br><span style="color: hsl(120, 100%, 40%);">+ </enum></span><br><span style="color: hsl(120, 100%, 40%);">+ </enumlist></span><br><span style="color: hsl(120, 100%, 40%);">+ </parameter></span><br><span style="color: hsl(120, 100%, 40%);">+ </syntax></span><br><span style="color: hsl(120, 100%, 40%);">+ <description></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>Returns the files that would be played by a Say application. These filenames could then be</span><br><span style="color: hsl(120, 100%, 40%);">+ passed directly into Playback, BackGround, Read, Queue, or any application which supports</span><br><span style="color: hsl(120, 100%, 40%);">+ playback of multiple ampersand-delimited files.</para></span><br><span style="color: hsl(120, 100%, 40%);">+ </description></span><br><span style="color: hsl(120, 100%, 40%);">+ <see-also></span><br><span style="color: hsl(120, 100%, 40%);">+ <ref type="application">SayAlpha</ref></span><br><span style="color: hsl(120, 100%, 40%);">+ <ref type="application">SayPhonetic</ref></span><br><span style="color: hsl(120, 100%, 40%);">+ <ref type="application">SayDigits</ref></span><br><span style="color: hsl(120, 100%, 40%);">+ </see-also></span><br><span style="color: hsl(120, 100%, 40%);">+ </function></span><br><span style="color: hsl(120, 100%, 40%);">+ ***/</span><br><span style="color: hsl(120, 100%, 40%);">+static int sayfile_exec(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ char *value, *type, *files;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_str *filenames = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_DECLARE_APP_ARGS(args,</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_APP_ARG(value);</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_APP_ARG(type);</span><br><span style="color: hsl(120, 100%, 40%);">+ );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_strlen_zero(data)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_WARNING, "SAYFILES requires an argument\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_STANDARD_APP_ARGS(args, data);</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+ value = args.value;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_strlen_zero(args.type))</span><br><span style="color: hsl(120, 100%, 40%);">+ type = "alpha";</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ type = args.type;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strcmp(type, "alpha")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ filenames = ast_get_character_str_full(value, ast_channel_language(chan), AST_SAY_CASE_NONE);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!strcmp(type, "phonetic")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ filenames = ast_get_phonetic_str_full(value, ast_channel_language(chan));</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!strcmp(type, "digits")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ filenames = ast_get_digit_str_full(value, ast_channel_language(chan));</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_WARNING, "Invalid say type specified: %s\n", type);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!filenames) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ files = ast_str_buffer(filenames);</span><br><span style="color: hsl(120, 100%, 40%);">+ snprintf(buf, len, "%s", files);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_free(filenames);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_custom_function sayfiles = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "SAYFILES",</span><br><span style="color: hsl(120, 100%, 40%);">+ .read = sayfile_exec,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int unload_module(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_custom_function_unregister(&sayfiles);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int load_module(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return ast_custom_function_register(&sayfiles);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Say application files");</span><br><span>diff --git a/include/asterisk/say.h b/include/asterisk/say.h</span><br><span>index a4aa90c..4359eff 100644</span><br><span>--- a/include/asterisk/say.h</span><br><span>+++ b/include/asterisk/say.h</span><br><span>@@ -188,4 +188,8 @@</span><br><span> }</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct ast_str* ast_get_character_str_full(const char *str, const char *lang, enum ast_say_case_sensitivity sensitivity);</span><br><span style="color: hsl(120, 100%, 40%);">+struct ast_str* ast_get_phonetic_str_full(const char *str, const char *lang);</span><br><span style="color: hsl(120, 100%, 40%);">+struct ast_str* ast_get_digit_str_full(const char *str, const char *lang);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #endif /* _ASTERISK_SAY_H */</span><br><span>diff --git a/main/say.c b/main/say.c</span><br><span>index 0a37091..1715aab 100644</span><br><span>--- a/main/say.c</span><br><span>+++ b/main/say.c</span><br><span>@@ -29,6 +29,8 @@</span><br><span> * Next Generation Networks (NGN).</span><br><span> * \note 2007-03-20 : Support for Thai added by Dome C. <dome@tel.co.th>,</span><br><span> * IP Crossing Co., Ltd.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \note 2021-07-26 : Refactoring to separate string buildup and playback</span><br><span style="color: hsl(120, 100%, 40%);">+ * by Naveen Albert <asterisk@phreaknet.org></span><br><span> */</span><br><span> </span><br><span> /*** MODULEINFO</span><br><span>@@ -58,9 +60,7 @@</span><br><span> /* Forward declaration */</span><br><span> static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int say_character_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity, int audiofd, int ctrlfd)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(120, 100%, 40%);">+struct ast_str* ast_get_character_str_full(const char *str, const char *lang, enum ast_say_case_sensitivity sensitivity) {</span><br><span> const char *fn;</span><br><span> char fnbuf[10], asciibuf[20] = "letters/ascii";</span><br><span> char ltr;</span><br><span>@@ -68,6 +68,9 @@</span><br><span> int res = 0;</span><br><span> int upper = 0;</span><br><span> int lower = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_str *filenames = ast_str_create(20);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_str_reset(filenames);</span><br><span> </span><br><span> while (str[num] && !res) {</span><br><span> fn = NULL;</span><br><span>@@ -154,14 +157,7 @@</span><br><span> }</span><br><span> if ((fn && ast_fileexists(fn, NULL, lang) > 0) ||</span><br><span> (snprintf(asciibuf + 13, sizeof(asciibuf) - 13, "%d", str[num]) > 0 && ast_fileexists(asciibuf, NULL, lang) > 0 && (fn = asciibuf))) {</span><br><span style="color: hsl(0, 100%, 40%);">- res = ast_streamfile(chan, fn, lang);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!res) {</span><br><span style="color: hsl(0, 100%, 40%);">- if ((audiofd > -1) && (ctrlfd > -1))</span><br><span style="color: hsl(0, 100%, 40%);">- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">- res = ast_waitstream(chan, ints);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ast_stopstream(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_str_append(&filenames, 0, (num == 0 ? "%s" : "&%s"), fn);</span><br><span> }</span><br><span> if (upper || lower) {</span><br><span> continue;</span><br><span>@@ -169,18 +165,44 @@</span><br><span> num++;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ return filenames;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int say_character_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity, int audiofd, int ctrlfd)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *fn;</span><br><span style="color: hsl(120, 100%, 40%);">+ int res = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_str *filenames = ast_get_character_str_full(str, lang, sensitivity);</span><br><span style="color: hsl(120, 100%, 40%);">+ char *files = ast_str_buffer(filenames);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ while ((fn = strsep(&files, "&"))) {</span><br><span style="color: hsl(120, 100%, 40%);">+ res = ast_streamfile(chan, fn, lang);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!res) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((audiofd > -1) && (ctrlfd > -1))</span><br><span style="color: hsl(120, 100%, 40%);">+ res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ res = ast_waitstream(chan, ints);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_stopstream(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+ ast_free(filenames);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> return res;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int say_phonetic_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)</span><br><span style="color: hsl(120, 100%, 40%);">+struct ast_str* ast_get_phonetic_str_full(const char *str, const char *lang)</span><br><span> {</span><br><span> const char *fn;</span><br><span> char fnbuf[256];</span><br><span> char ltr;</span><br><span> int num = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- int res = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_str *filenames = ast_str_create(20);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_str_reset(filenames);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- while (str[num] && !res) {</span><br><span style="color: hsl(120, 100%, 40%);">+ while (str[num]) {</span><br><span> fn = NULL;</span><br><span> switch (str[num]) {</span><br><span> case ('*'):</span><br><span>@@ -237,29 +259,48 @@</span><br><span> fn = fnbuf;</span><br><span> }</span><br><span> if (fn && ast_fileexists(fn, NULL, lang) > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- res = ast_streamfile(chan, fn, lang);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!res) {</span><br><span style="color: hsl(0, 100%, 40%);">- if ((audiofd > -1) && (ctrlfd > -1))</span><br><span style="color: hsl(0, 100%, 40%);">- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">- res = ast_waitstream(chan, ints);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ast_stopstream(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_str_append(&filenames, 0, (num == 0 ? "%s" : "&%s"), fn);</span><br><span> }</span><br><span> num++;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ return filenames;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int say_phonetic_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *fn;</span><br><span style="color: hsl(120, 100%, 40%);">+ int res = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_str *filenames = ast_get_phonetic_str_full(str, lang);</span><br><span style="color: hsl(120, 100%, 40%);">+ char *files = ast_str_buffer(filenames);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ while ((fn = strsep(&files, "&"))) {</span><br><span style="color: hsl(120, 100%, 40%);">+ res = ast_streamfile(chan, fn, lang);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!res) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((audiofd > -1) && (ctrlfd > -1))</span><br><span style="color: hsl(120, 100%, 40%);">+ res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ res = ast_waitstream(chan, ints);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_stopstream(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_free(filenames);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> return res;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int say_digit_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)</span><br><span style="color: hsl(120, 100%, 40%);">+struct ast_str* ast_get_digit_str_full(const char *str, const char *lang)</span><br><span> {</span><br><span> const char *fn;</span><br><span> char fnbuf[256];</span><br><span> int num = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- int res = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_str *filenames = ast_str_create(20);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_str_reset(filenames);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- while (str[num] && !res) {</span><br><span style="color: hsl(120, 100%, 40%);">+ while (str[num]) {</span><br><span> fn = NULL;</span><br><span> switch (str[num]) {</span><br><span> case ('*'):</span><br><span>@@ -287,18 +328,35 @@</span><br><span> break;</span><br><span> }</span><br><span> if (fn && ast_fileexists(fn, NULL, lang) > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- res = ast_streamfile(chan, fn, lang);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!res) {</span><br><span style="color: hsl(0, 100%, 40%);">- if ((audiofd > -1) && (ctrlfd > -1))</span><br><span style="color: hsl(0, 100%, 40%);">- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">- res = ast_waitstream(chan, ints);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ast_stopstream(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_str_append(&filenames, 0, (num == 0 ? "%s" : "&%s"), fn);</span><br><span> }</span><br><span> num++;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ return filenames;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int say_digit_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *fn;</span><br><span style="color: hsl(120, 100%, 40%);">+ int res = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_str *filenames = ast_get_digit_str_full(str, lang);</span><br><span style="color: hsl(120, 100%, 40%);">+ char *files = ast_str_buffer(filenames);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ while ((fn = strsep(&files, "&"))) {</span><br><span style="color: hsl(120, 100%, 40%);">+ res = ast_streamfile(chan, fn, lang);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!res) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((audiofd > -1) && (ctrlfd > -1))</span><br><span style="color: hsl(120, 100%, 40%);">+ res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ res = ast_waitstream(chan, ints);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_stopstream(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_free(filenames);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> return res;</span><br><span> }</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/16226">change 16226</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/16226"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: If9718c89353b8e153d84add3cc4637b79585db19 </div>
<div style="display:none"> Gerrit-Change-Number: 16226 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: N A <mail@interlinked.x10host.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>