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