<p>Friendly Automation <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/19289">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span></span><br></pre><div style="white-space:pre-wrap">Approvals:
  Joshua Colp: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved
  Friendly Automation: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">func_strings: Add trim functions.<br><br>Adds TRIM, LTRIM, and RTRIM, which can be used<br>for trimming leading and trailing whitespace<br>from strings.<br><br>ASTERISK-30222 #close<br><br>Change-Id: I50fb0c40726d044a7a41939fa9026f3da4872554<br>---<br>A doc/CHANGES-staging/func_strings_trim.txt<br>M funcs/func_strings.c<br>2 files changed, 205 insertions(+), 1 deletion(-)<br><br></pre>
<pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/doc/CHANGES-staging/func_strings_trim.txt b/doc/CHANGES-staging/func_strings_trim.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..ade7a4b</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/func_strings_trim.txt</span><br><span>@@ -0,0 +1,5 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: func_strings</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Three new functions, TRIM, LTRIM, and RTRIM, are</span><br><span style="color: hsl(120, 100%, 40%);">+now available for trimming leading and trailing</span><br><span style="color: hsl(120, 100%, 40%);">+whitespace.</span><br><span>diff --git a/funcs/func_strings.c b/funcs/func_strings.c</span><br><span>index 77cdc99..598e6a4 100644</span><br><span>--- a/funcs/func_strings.c</span><br><span>+++ b/funcs/func_strings.c</span><br><span>@@ -4,7 +4,7 @@</span><br><span>  * Copyright (C) 2005-2006, Digium, Inc.</span><br><span>  * Portions Copyright (C) 2005, Tilghman Lesher.  All rights reserved.</span><br><span>  * Portions Copyright (C) 2005, Anthony Minessale II</span><br><span style="color: hsl(0, 100%, 40%);">- * Portions Copyright (C) 2021, Naveen Albert</span><br><span style="color: hsl(120, 100%, 40%);">+ * Portions Copyright (C) 2021, 2022, Naveen Albert</span><br><span>  *</span><br><span>  * See http://www.asterisk.org for more information about</span><br><span>  * the Asterisk project. Please do not directly contact</span><br><span>@@ -183,6 +183,51 @@</span><br><span>                        </example></span><br><span>             </description></span><br><span>         </function></span><br><span style="color: hsl(120, 100%, 40%);">+     <function name="TRIM" language="en_US"></span><br><span style="color: hsl(120, 100%, 40%);">+             <synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+                      Trim leading and trailing whitespace in a string</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="string" required="true" /></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>Replaces all leading and trailing whitespace in the provided string.</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="function">LTRIM</ref></span><br><span style="color: hsl(120, 100%, 40%);">+                        <ref type="function">RTRIM</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%);">+     <function name="LTRIM" language="en_US"></span><br><span style="color: hsl(120, 100%, 40%);">+            <synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+                      Trim leading whitespace in a string</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="string" required="true" /></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>Replaces all leading whitespace in the provided string.</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="function">TRIM</ref></span><br><span style="color: hsl(120, 100%, 40%);">+                 <ref type="function">RTRIM</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%);">+     <function name="RTRIM" language="en_US"></span><br><span style="color: hsl(120, 100%, 40%);">+            <synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+                      Trim trailing whitespace in a string</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="string" required="true" /></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>Replaces all trailing whitespace in the provided string.</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="function">TRIM</ref></span><br><span style="color: hsl(120, 100%, 40%);">+                 <ref type="function">LTRIM</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>    <function name="PASSTHRU" language="en_US"></span><br><span>                <synopsis></span><br><span>                     Pass the given argument back as a value.</span><br><span>@@ -1045,6 +1090,84 @@</span><br><span>    .read2 = strbetween,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define ltrim(s) while (isspace(*s)) s++;</span><br><span style="color: hsl(120, 100%, 40%);">+#define rtrim(s) { \</span><br><span style="color: hsl(120, 100%, 40%);">+       if (s) { \</span><br><span style="color: hsl(120, 100%, 40%);">+            char *back = s + strlen(s); \</span><br><span style="color: hsl(120, 100%, 40%);">+         while (back != s && isspace(*--back)); \</span><br><span style="color: hsl(120, 100%, 40%);">+              if (*s) { \</span><br><span style="color: hsl(120, 100%, 40%);">+                   *(back + 1) = '\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%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int function_trim(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 *c;</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%);">+          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%);">+   c = ast_strdupa(data);</span><br><span style="color: hsl(120, 100%, 40%);">+        ltrim(c);</span><br><span style="color: hsl(120, 100%, 40%);">+     rtrim(c);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_copy_string(buf, c, len);</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 function_ltrim(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 *c;</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%);">+          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%);">+   c = data;</span><br><span style="color: hsl(120, 100%, 40%);">+     ltrim(c);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_copy_string(buf, c, len);</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 function_rtrim(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 *c;</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%);">+          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%);">+   c = ast_strdupa(data);</span><br><span style="color: hsl(120, 100%, 40%);">+        rtrim(c);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_copy_string(buf, c, len);</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%);">+#undef ltrim</span><br><span style="color: hsl(120, 100%, 40%);">+#undef rtrim</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_custom_function trim_function = {</span><br><span style="color: hsl(120, 100%, 40%);">+     .name = "TRIM",</span><br><span style="color: hsl(120, 100%, 40%);">+     .read = function_trim,</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 ltrim_function = {</span><br><span style="color: hsl(120, 100%, 40%);">+    .name = "LTRIM",</span><br><span style="color: hsl(120, 100%, 40%);">+    .read = function_ltrim,</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 rtrim_function = {</span><br><span style="color: hsl(120, 100%, 40%);">+   .name = "RTRIM",</span><br><span style="color: hsl(120, 100%, 40%);">+    .read = function_rtrim,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf,</span><br><span>                  size_t len)</span><br><span> {</span><br><span>@@ -2126,6 +2249,59 @@</span><br><span> </span><br><span>       return res;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AST_TEST_DEFINE(test_TRIM)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     int i, res = AST_TEST_PASS;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct ast_channel *chan; /* dummy channel */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_str *str; /* fancy string for holding comparing value */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *test_strings[][5] = {</span><br><span style="color: hsl(120, 100%, 40%);">+             {"TRIM", "  abcd ", "abcd"},</span><br><span style="color: hsl(120, 100%, 40%);">+            {"LTRIM", " abcd ", "abcd "},</span><br><span style="color: hsl(120, 100%, 40%);">+           {"RTRIM", " abcd ", " abcd"},</span><br><span style="color: hsl(120, 100%, 40%);">+           {"TRIM", "abcd", "abcd"},</span><br><span style="color: hsl(120, 100%, 40%);">+               {"TRIM", " a b c d ", "a b c d"},</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%);">+  switch (cmd) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case TEST_INIT:</span><br><span style="color: hsl(120, 100%, 40%);">+               info->name = "func_TRIM";</span><br><span style="color: hsl(120, 100%, 40%);">+                info->category = "/funcs/func_strings/";</span><br><span style="color: hsl(120, 100%, 40%);">+         info->summary = "Test TRIM functions";</span><br><span style="color: hsl(120, 100%, 40%);">+           info->description = "Verify TRIM behavior";</span><br><span style="color: hsl(120, 100%, 40%);">+              return AST_TEST_NOT_RUN;</span><br><span style="color: hsl(120, 100%, 40%);">+      case TEST_EXECUTE:</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</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 (!(chan = ast_dummy_channel_alloc())) {</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_test_status_update(test, "Unable to allocate dummy channel\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         return AST_TEST_FAIL;</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 (!(str = ast_str_create(64))) {</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_test_status_update(test, "Unable to allocate dynamic string buffer\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         ast_channel_release(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+            return AST_TEST_FAIL;</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%);">+   for (i = 0; i < ARRAY_LEN(test_strings); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+            char tmp[512], tmp2[512] = "";</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            snprintf(tmp, sizeof(tmp), "${%s(%s)}", test_strings[i][0], test_strings[i][1]);</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_str_substitute_variables(&str, 0, chan, tmp);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (strcmp(test_strings[i][2], ast_str_buffer(str))) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        ast_test_status_update(test, "Format string '%s' substituted to '%s'.  Expected '%s'.\n", test_strings[i][0], tmp2, test_strings[i][2]);</span><br><span style="color: hsl(120, 100%, 40%);">+                    res = AST_TEST_FAIL;</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_free(str);</span><br><span style="color: hsl(120, 100%, 40%);">+        ast_channel_release(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return res;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> #endif</span><br><span> </span><br><span> static int unload_module(void)</span><br><span>@@ -2137,6 +2313,7 @@</span><br><span>       AST_TEST_UNREGISTER(test_FILTER);</span><br><span>    AST_TEST_UNREGISTER(test_STRREPLACE);</span><br><span>        AST_TEST_UNREGISTER(test_STRBETWEEN);</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_TEST_UNREGISTER(test_TRIM);</span><br><span>      res |= ast_custom_function_unregister(&fieldqty_function);</span><br><span>       res |= ast_custom_function_unregister(&fieldnum_function);</span><br><span>       res |= ast_custom_function_unregister(&filter_function);</span><br><span>@@ -2163,6 +2340,9 @@</span><br><span>         res |= ast_custom_function_unregister(&push_function);</span><br><span>   res |= ast_custom_function_unregister(&unshift_function);</span><br><span>        res |= ast_custom_function_unregister(&passthru_function);</span><br><span style="color: hsl(120, 100%, 40%);">+        res |= ast_custom_function_unregister(&trim_function);</span><br><span style="color: hsl(120, 100%, 40%);">+    res |= ast_custom_function_unregister(&ltrim_function);</span><br><span style="color: hsl(120, 100%, 40%);">+   res |= ast_custom_function_unregister(&rtrim_function);</span><br><span> </span><br><span>      return res;</span><br><span> }</span><br><span>@@ -2176,6 +2356,7 @@</span><br><span>     AST_TEST_REGISTER(test_FILTER);</span><br><span>      AST_TEST_REGISTER(test_STRREPLACE);</span><br><span>  AST_TEST_REGISTER(test_STRBETWEEN);</span><br><span style="color: hsl(120, 100%, 40%);">+   AST_TEST_REGISTER(test_TRIM);</span><br><span>        res |= ast_custom_function_register(&fieldqty_function);</span><br><span>         res |= ast_custom_function_register(&fieldnum_function);</span><br><span>         res |= ast_custom_function_register(&filter_function);</span><br><span>@@ -2202,6 +2383,9 @@</span><br><span>   res |= ast_custom_function_register(&push_function);</span><br><span>     res |= ast_custom_function_register(&unshift_function);</span><br><span>  res |= ast_custom_function_register(&passthru_function);</span><br><span style="color: hsl(120, 100%, 40%);">+  res |= ast_custom_function_register(&trim_function);</span><br><span style="color: hsl(120, 100%, 40%);">+      res |= ast_custom_function_register(&ltrim_function);</span><br><span style="color: hsl(120, 100%, 40%);">+     res |= ast_custom_function_register(&rtrim_function);</span><br><span> </span><br><span>        return res;</span><br><span> }</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/19289">change 19289</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/+/19289"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 16 </div>
<div style="display:none"> Gerrit-Change-Id: I50fb0c40726d044a7a41939fa9026f3da4872554 </div>
<div style="display:none"> Gerrit-Change-Number: 19289 </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-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>