<p>Friendly Automation <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/14617">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Kevin Harwell: Looks good to me, but someone else must approve
  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;">Scope Trace:  Add some new tracing macros and an ast_str helper<br><br>Created new SCOPE_ functions that don't depend on RAII_VAR.  Besides<br>generating less code, the use of the explicit SCOPE_EXIT macros<br>capture the line number where the scope exited.  The RAII_VAR<br>versions can't do that.<br><br> * SCOPE_ENTER(level, ...): Like SCOPE_TRACE but doesn't use<br>   RAII_VAR and therefore needs needs one of...<br><br> * SCOPE_EXIT(...): Decrements the trace stack counter and optionally<br>   prints a message.<br><br> * SCOPE_EXIT_EXPR(__expr, ...): Decrements the trace stack counter,<br>   optionally prints a message, then executes the expression.<br>   SCOPE_EXIT_EXPR(break, "My while got broken\n");<br><br> * SCOPE_EXIT_RTN(, ...): Decrements the trace stack counter,<br>   optionally prints a message, then returns without a value.<br>   SCOPE_EXIT_RTN("Bye\n");<br><br> * SCOPE_EXIT_RTN_VALUE(__return_value, ...): Decrements the trace<br>   stack counter, optionally prints a message, then returns the value<br>   specified.<br>   SCOPE_EXIT_RTN_VALUE(rc, "Returning with RC: %d\n", rc);<br><br>Create an ast_str helper ast_str_tmp() that allocates a temporary<br>ast_str that can be passed to a function that needs it, then frees<br>it.  This makes using the above macros easier.  Example:<br><br>   SCOPE_ENTER(1, Format Caps 1: %s  Format Caps 2: %s\n",<br>       ast_str_tmp(32, ast_format_cap_get_names(cap1, &STR_TMP),<br>       ast_str_tmp(32, ast_format_cap_get_names(cap2, &STR_TMP));<br><br>The calls to ast_str_tmp create an ast_str of the specified initial<br>length which can be referenced as STR_TMP.  It then calls the<br>expression, which must return a char *, ast_strdupa's it, frees<br>STR_TMP, then returns the ast_strdupa'd string.  That string is<br>freed when the function returns.<br><br>Change-Id: I44059b20d55a889aa91440d2f8a590865998be51<br>---<br>M include/asterisk/logger.h<br>M include/asterisk/strings.h<br>M tests/test_scope_trace.c<br>M tests/test_strings.c<br>4 files changed, 232 insertions(+), 24 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/asterisk/logger.h b/include/asterisk/logger.h</span><br><span>index 4392e5a..67e4df7 100644</span><br><span>--- a/include/asterisk/logger.h</span><br><span>+++ b/include/asterisk/logger.h</span><br><span>@@ -715,10 +715,107 @@</span><br><span>        } \</span><br><span>  int __scopevar ## __LINE__ ## __RETURN __attribute__((unused)) = __scopevar ## __LINE__ ## __ENTER()</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Non RAII_VAR Scope Trace macros</span><br><span style="color: hsl(120, 100%, 40%);">+ * The advantage of these macros is that the EXITs will have the actual</span><br><span style="color: hsl(120, 100%, 40%);">+ * line number where the scope exited.  Much less code is required as well.</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%);">+ * \brief Scope Enter</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param level The trace level</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param (optional) A printf style format string</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param (optional) Arguments</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#define SCOPE_ENTER(level, ...) \</span><br><span style="color: hsl(120, 100%, 40%);">+     int __scope_level = level; \</span><br><span style="color: hsl(120, 100%, 40%);">+  if (TRACE_ATLEAST(level)) { \</span><br><span style="color: hsl(120, 100%, 40%);">+         __ast_trace(__FILE__, __LINE__, __PRETTY_FUNCTION__, AST_TRACE_INDENT_INC_AFTER, " " __VA_ARGS__); \</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%);">+ * \brief Scope Exit</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param (optional) A printf style format string</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param (optional) Arguments</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \details</span><br><span style="color: hsl(120, 100%, 40%);">+ * This macro can be used at the exit points of a statement block since it just prints the message.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#define SCOPE_EXIT(...) \</span><br><span style="color: hsl(120, 100%, 40%);">+ if (TRACE_ATLEAST(__scope_level)) { \</span><br><span style="color: hsl(120, 100%, 40%);">+         __ast_trace(__FILE__, __LINE__, __PRETTY_FUNCTION__, AST_TRACE_INDENT_DEC_BEFORE, " " __VA_ARGS__); \</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%);">+ * \brief Scope Exit with expression</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param __expr An expression to execute after printing the message</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param (optional) A printf style format string</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param (optional) Arguments</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \details</span><br><span style="color: hsl(120, 100%, 40%);">+ * Handy for getting out of or continuing loops.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \example</span><br><span style="color: hsl(120, 100%, 40%);">+ * while(something) {</span><br><span style="color: hsl(120, 100%, 40%);">+ *     SCOPE_ENTER(2, "In a while\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ *     if (something) {</span><br><span style="color: hsl(120, 100%, 40%);">+ *         SCOPE_EXIT_EXPR(break, "Somethiung broke me\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ *     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ *         SCOPE_EXIT_EXPR(contniue, "Somethiung continued me\n");</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%);">+#define SCOPE_EXIT_EXPR(__expr, ...) \</span><br><span style="color: hsl(120, 100%, 40%);">+        if (TRACE_ATLEAST(__scope_level)) { \</span><br><span style="color: hsl(120, 100%, 40%);">+         __ast_trace(__FILE__, __LINE__, __PRETTY_FUNCTION__, AST_TRACE_INDENT_DEC_BEFORE, " " __VA_ARGS__); \</span><br><span style="color: hsl(120, 100%, 40%);">+       } \</span><br><span style="color: hsl(120, 100%, 40%);">+   __expr</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%);">+ * \brief Scope Exit with return</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param (optional) A printf style format string</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param (optional) Arguments</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \details</span><br><span style="color: hsl(120, 100%, 40%);">+ * This macro can be used at the exit points of a function when no value</span><br><span style="color: hsl(120, 100%, 40%);">+ * needs to be returned.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#define SCOPE_EXIT_RTN(...) \</span><br><span style="color: hsl(120, 100%, 40%);">+       if (TRACE_ATLEAST(__scope_level)) { \</span><br><span style="color: hsl(120, 100%, 40%);">+         __ast_trace(__FILE__, __LINE__, __PRETTY_FUNCTION__, AST_TRACE_INDENT_DEC_BEFORE, " " __VA_ARGS__); \</span><br><span style="color: hsl(120, 100%, 40%);">+       } \</span><br><span style="color: hsl(120, 100%, 40%);">+   return</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%);">+ * \brief Scope Exit with return value</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param __return_value The return value</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param (optional) A printf style format string</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param (optional) Arguments</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \details</span><br><span style="color: hsl(120, 100%, 40%);">+ * This macro can be used at the exit points of a function when a value</span><br><span style="color: hsl(120, 100%, 40%);">+ * needs to be returned.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#define SCOPE_EXIT_RTN_VALUE(__return_value, ...) \</span><br><span style="color: hsl(120, 100%, 40%);">+ if (TRACE_ATLEAST(__scope_level)) { \</span><br><span style="color: hsl(120, 100%, 40%);">+         __ast_trace(__FILE__, __LINE__, __PRETTY_FUNCTION__, AST_TRACE_INDENT_DEC_BEFORE, " " __VA_ARGS__); \</span><br><span style="color: hsl(120, 100%, 40%);">+       } \</span><br><span style="color: hsl(120, 100%, 40%);">+   return(__return_value)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #else</span><br><span style="color: hsl(0, 100%, 40%);">-#define ast_trace_raw(__level, __indent_type, __fmt, ...)</span><br><span style="color: hsl(0, 100%, 40%);">-#define ast_trace(__level)</span><br><span style="color: hsl(0, 100%, 40%);">-#define SCOPE_TRACE(__level)</span><br><span style="color: hsl(120, 100%, 40%);">+#define ast_trace_raw(__level, __indent_type, ...)</span><br><span style="color: hsl(120, 100%, 40%);">+#define ast_trace(__level, ...)</span><br><span style="color: hsl(120, 100%, 40%);">+#define SCOPE_TRACE(__level, ...)</span><br><span style="color: hsl(120, 100%, 40%);">+#define SCOPE_ENTER(level, ...)</span><br><span style="color: hsl(120, 100%, 40%);">+#define SCOPE_EXIT(...)</span><br><span style="color: hsl(120, 100%, 40%);">+#define SCOPE_EXIT_EXPR(__expr, ...)</span><br><span style="color: hsl(120, 100%, 40%);">+#define SCOPE_EXIT_RTN(...)</span><br><span style="color: hsl(120, 100%, 40%);">+#define SCOPE_EXIT_RTN_VALUE(__return_value, ...)</span><br><span> #endif</span><br><span> </span><br><span> #if defined(__cplusplus) || defined(c_plusplus)</span><br><span>diff --git a/include/asterisk/strings.h b/include/asterisk/strings.h</span><br><span>index c56a139..e9d786c 100644</span><br><span>--- a/include/asterisk/strings.h</span><br><span>+++ b/include/asterisk/strings.h</span><br><span>@@ -1091,6 +1091,59 @@</span><br><span> )</span><br><span> </span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Provides a temporary ast_str and returns a copy of its buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 16.12</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 17.6</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 18.0</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param init_len The initial length of the temporary ast_str needed.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param __expr An expression that needs the temporary ast_str and returns a char *.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \returns A copy of __expr's return buffer allocated on the stack.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \details</span><br><span style="color: hsl(120, 100%, 40%);">+ * There are a few query functions scattered around that need an ast_str in which</span><br><span style="color: hsl(120, 100%, 40%);">+ * to assemble the results but it's not always convenient to create an ast_str</span><br><span style="color: hsl(120, 100%, 40%);">+ * and ensure it's freed just to print a log message.  For example...</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * struct ast_str *temp = ast_str_create(128);</span><br><span style="color: hsl(120, 100%, 40%);">+ * ast_log(LOG_INFO, "Format caps: %s\n", ast_format_cap_get_names(caps, &temp));</span><br><span style="color: hsl(120, 100%, 40%);">+ * ast_free(temp);</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * That's not bad if you only have to do it once but some of our code that deals</span><br><span style="color: hsl(120, 100%, 40%);">+ * with streams and codecs is pretty complex and good instrumentation is essential.</span><br><span style="color: hsl(120, 100%, 40%);">+ * The aim of this function is to make that easier.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * With this macro, the above code can be simplified as follows...</span><br><span style="color: hsl(120, 100%, 40%);">+ * \example</span><br><span style="color: hsl(120, 100%, 40%);">+ * ast_log(LOG_INFO, "Format caps: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ *     ast_str_tmp(128, ast_format_cap_get_names(caps, &STR_TMP));</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * STR_TMP will always be a reference to the temporary ast_str created</span><br><span style="color: hsl(120, 100%, 40%);">+ * by the macro.  Its scope is limited by the macro so you can use it multiple</span><br><span style="color: hsl(120, 100%, 40%);">+ * times without conflict.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \example</span><br><span style="color: hsl(120, 100%, 40%);">+ * ast_log(LOG_INFO, "Format caps in: %s  Format caps out: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ *     ast_str_tmp(128, ast_format_cap_get_names(caps_in, &STR_TMP),</span><br><span style="color: hsl(120, 100%, 40%);">+ *     ast_str_tmp(128, ast_format_cap_get_names(caps_out, &STR_TMP)</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%);">+ * \warning</span><br><span style="color: hsl(120, 100%, 40%);">+ * The returned string is stack allocated so don't go overboard.</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%);">+#define ast_str_tmp(init_len, __expr) \</span><br><span style="color: hsl(120, 100%, 40%);">+({ \</span><br><span style="color: hsl(120, 100%, 40%);">+      struct ast_str *STR_TMP = ast_str_create(init_len); \</span><br><span style="color: hsl(120, 100%, 40%);">+ char *ret = ast_strdupa(__expr); \</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_free(STR_TMP); \</span><br><span style="color: hsl(120, 100%, 40%);">+  ret; \</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%);">+/*!</span><br><span>  * \brief Check if a string is only digits</span><br><span>  *</span><br><span>  * \retval 1 The string contains only digits</span><br><span>diff --git a/tests/test_scope_trace.c b/tests/test_scope_trace.c</span><br><span>index 6ab480a..56f0875 100644</span><br><span>--- a/tests/test_scope_trace.c</span><br><span>+++ b/tests/test_scope_trace.c</span><br><span>@@ -38,58 +38,77 @@</span><br><span> #include "asterisk/test.h"</span><br><span> #include "asterisk/logger.h"</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void test_scope2(void)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const char *str_appender(struct ast_str**buf, char *a)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   SCOPE_TRACE(1);</span><br><span style="color: hsl(120, 100%, 40%);">+       ast_str_append(buf, 0, "<append %s>", a);</span><br><span style="color: hsl(120, 100%, 40%);">+     return ast_str_buffer(*buf);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void test_scope(void)</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_scope_trace(void)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      SCOPE_TRACE(1, "nested function: %d * %d = %d\n", 6, 7, (6 * 7));</span><br><span style="color: hsl(120, 100%, 40%);">+   SCOPE_ENTER(1, "subfunction\n");</span><br><span style="color: hsl(120, 100%, 40%);">+    SCOPE_EXIT_RTN("got out\n");</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   test_scope2();</span><br><span style="color: hsl(120, 100%, 40%);">+static int test_scope_enter_function(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ SCOPE_ENTER(1, "%s %s %s %s %s %s %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_str_tmp(12, str_appender(&STR_TMP, "str1")),</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_str_tmp(12, str_appender(&STR_TMP, "str2")),</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_str_tmp(32, str_appender(&STR_TMP, "AAAAAAAAAAAAAAAAAAAAAAAA")),</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_str_tmp(12, str_appender(&STR_TMP, "B")),</span><br><span style="color: hsl(120, 100%, 40%);">+           "ccccccccccccc",</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_str_tmp(12, str_appender(&STR_TMP, "DDDDD")),</span><br><span style="color: hsl(120, 100%, 40%);">+               ast_str_tmp(12, str_appender(&STR_TMP, "ww"))</span><br><span style="color: hsl(120, 100%, 40%);">+           );</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  ast_trace(1, "test no variables\n");</span><br><span style="color: hsl(120, 100%, 40%);">+        test_scope_trace();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ SCOPE_EXIT_RTN_VALUE(AST_TEST_PASS, "test no variables\n");</span><br><span> }</span><br><span> </span><br><span> </span><br><span> AST_TEST_DEFINE(scope_test)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  SCOPE_TRACE(1, "top %s function\n", "scope_test");</span><br><span style="color: hsl(120, 100%, 40%);">+        SCOPE_ENTER(1, "top %s function\n", "scope_test");</span><br><span> </span><br><span>   ast_trace(1, "%s\n", "test outer");</span><br><span> </span><br><span>  switch (cmd) {</span><br><span>       case TEST_INIT:</span><br><span style="color: hsl(120, 100%, 40%);">+       {</span><br><span style="color: hsl(120, 100%, 40%);">+             SCOPE_ENTER(1, "TEST_INIT\n");</span><br><span>             info->name = "scope_test";</span><br><span>              info->category = "/main/logging/";</span><br><span>              info->summary = "Scope Trace Tests";</span><br><span>            info->description = "Scope Trace Tests";</span><br><span style="color: hsl(0, 100%, 40%);">-           return AST_TEST_NOT_RUN;</span><br><span style="color: hsl(120, 100%, 40%);">+              /* need to exit the case scope */</span><br><span style="color: hsl(120, 100%, 40%);">+             SCOPE_EXIT("TEST_INIT\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          /* need to exit the function */</span><br><span style="color: hsl(120, 100%, 40%);">+               SCOPE_EXIT_RTN_VALUE(AST_TEST_NOT_RUN, "BYE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span>    case TEST_EXECUTE:</span><br><span style="color: hsl(0, 100%, 40%);">-              {</span><br><span style="color: hsl(0, 100%, 40%);">-                       SCOPE_TRACE(1, "CASE statement\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                   ast_trace(1, "%s\n", "test case");</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        {</span><br><span style="color: hsl(120, 100%, 40%);">+             SCOPE_ENTER(1, "TEST_EXECUTE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_trace(1, "%s\n", "test execute");</span><br><span style="color: hsl(120, 100%, 40%);">+             SCOPE_EXIT_EXPR(break, "TEST_EXECUTE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     default:</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_test_status_update(test, "Shouldn't have gotten here\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return AST_TEST_FAIL;</span><br><span>        }</span><br><span> </span><br><span>        if (1) {</span><br><span>             SCOPE_TRACE(1, "IF block\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-         test_scope();</span><br><span style="color: hsl(120, 100%, 40%);">+         test_scope_enter_function();</span><br><span>         }</span><br><span> </span><br><span>        ast_trace(1);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>        ast_trace(1, "test no variables\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>       ast_trace(1, "%s\n", "test variable");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  return AST_TEST_PASS;</span><br><span style="color: hsl(120, 100%, 40%);">+ SCOPE_EXIT_RTN_VALUE(AST_TEST_PASS, "Something: %d\n", AST_TEST_PASS);</span><br><span> }</span><br><span> </span><br><span> static int unload_module(void)</span><br><span>diff --git a/tests/test_strings.c b/tests/test_strings.c</span><br><span>index 90b0d36..3d697e5 100644</span><br><span>--- a/tests/test_strings.c</span><br><span>+++ b/tests/test_strings.c</span><br><span>@@ -583,6 +583,43 @@</span><br><span>      return AST_TEST_PASS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Function that needs a temporary ast_str</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static const char *str_appender(struct ast_str**buf, char *a)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_str_append(buf, 0, "<%s>", a);</span><br><span style="color: hsl(120, 100%, 40%);">+    return ast_str_buffer(*buf);</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_TEST_DEFINE(temp_strings)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   char *return_buffer = ast_malloc(128);</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 = "temp_strings";</span><br><span style="color: hsl(120, 100%, 40%);">+             info->category = "/main/strings/";</span><br><span style="color: hsl(120, 100%, 40%);">+               info->summary = "Test ast_str_temp_buffer";</span><br><span style="color: hsl(120, 100%, 40%);">+              info->description = "Test ast_str_temp_buffer";</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%);">+   snprintf(return_buffer, 128, "%s %s %s %s %s",</span><br><span style="color: hsl(120, 100%, 40%);">+      ast_str_tmp(12, str_appender(&STR_TMP, "str1")),</span><br><span style="color: hsl(120, 100%, 40%);">+        ast_str_tmp(12, str_appender(&STR_TMP, "str2")),</span><br><span style="color: hsl(120, 100%, 40%);">+        ast_str_tmp(12, str_appender(&STR_TMP, "B")),</span><br><span style="color: hsl(120, 100%, 40%);">+   "ccccccccccccc",</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_str_tmp(12, str_appender(&STR_TMP, "ww"))</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_test_validate(test, ast_strings_match(return_buffer, "=", "<str1> <str2> <B> ccccccccccccc <ww>"));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_free(return_buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+      return AST_TEST_PASS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int unload_module(void)</span><br><span> {</span><br><span>    AST_TEST_UNREGISTER(str_test);</span><br><span>@@ -592,6 +629,7 @@</span><br><span>         AST_TEST_UNREGISTER(escape_semicolons_test);</span><br><span>         AST_TEST_UNREGISTER(escape_test);</span><br><span>    AST_TEST_UNREGISTER(strings_match);</span><br><span style="color: hsl(120, 100%, 40%);">+   AST_TEST_UNREGISTER(temp_strings);</span><br><span>   return 0;</span><br><span> }</span><br><span> </span><br><span>@@ -604,6 +642,7 @@</span><br><span>     AST_TEST_REGISTER(escape_semicolons_test);</span><br><span>   AST_TEST_REGISTER(escape_test);</span><br><span>      AST_TEST_REGISTER(strings_match);</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_TEST_REGISTER(temp_strings);</span><br><span>     return AST_MODULE_LOAD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/14617">change 14617</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/+/14617"/><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: I44059b20d55a889aa91440d2f8a590865998be51 </div>
<div style="display:none"> Gerrit-Change-Number: 14617 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: George Joseph <gjoseph@digium.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-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>