<p>Neels Hofmeyr <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/13594">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">tweak OSMO_STRBUF_APPEND(), add OSMO_STRBUF_APPEND_NOLEN()<br><br>In OSMO_STRBUF_APPEND, use local variable names that are less likely to shadow<br>other local variables: prefix with _sb_.<br><br>In OSMO_STRBUF_APPEND, add a check to add to .pos only if it is not NULL.<br><br>Add OSMO_STRBUF_APPEND_NOLEN(), which works for function signatures that don't<br>return a length. This is useful for any osmo_*_buf() string writing functions,<br>so that these write directly to the strbuf.<br><br>Change-Id: I108cadf72deb3a3bcab9a07e50572d9da1ab0359<br>---<br>M include/osmocom/core/utils.h<br>M tests/utils/utils_test.c<br>M tests/utils/utils_test.ok<br>3 files changed, 53 insertions(+), 7 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h</span><br><span>index 474e36c..f13c1e4 100644</span><br><span>--- a/include/osmocom/core/utils.h</span><br><span>+++ b/include/osmocom/core/utils.h</span><br><span>@@ -205,14 +205,14 @@</span><br><span> #define OSMO_STRBUF_APPEND(STRBUF, func, args...) do { \</span><br><span>            if (!(STRBUF).pos) \</span><br><span>                         (STRBUF).pos = (STRBUF).buf; \</span><br><span style="color: hsl(0, 100%, 40%);">-          size_t remain = (STRBUF).buf ? (STRBUF).len - ((STRBUF).pos - (STRBUF).buf) : 0; \</span><br><span style="color: hsl(0, 100%, 40%);">-              int l = func((STRBUF).pos, remain, ##args); \</span><br><span style="color: hsl(0, 100%, 40%);">-           if (l < 0 || l > remain) \</span><br><span style="color: hsl(120, 100%, 40%);">+              size_t _sb_remain = (STRBUF).buf ? (STRBUF).len - ((STRBUF).pos - (STRBUF).buf) : 0; \</span><br><span style="color: hsl(120, 100%, 40%);">+                int _sb_l = func((STRBUF).pos, _sb_remain, ##args); \</span><br><span style="color: hsl(120, 100%, 40%);">+         if (_sb_l < 0 || _sb_l > _sb_remain) \</span><br><span>                         (STRBUF).pos = (STRBUF).buf + (STRBUF).len; \</span><br><span style="color: hsl(0, 100%, 40%);">-           else \</span><br><span style="color: hsl(0, 100%, 40%);">-                  (STRBUF).pos += l; \</span><br><span style="color: hsl(0, 100%, 40%);">-            if (l > 0) \</span><br><span style="color: hsl(0, 100%, 40%);">-                 (STRBUF).chars_needed += l; \</span><br><span style="color: hsl(120, 100%, 40%);">+         else if ((STRBUF).pos) \</span><br><span style="color: hsl(120, 100%, 40%);">+                      (STRBUF).pos += _sb_l; \</span><br><span style="color: hsl(120, 100%, 40%);">+              if (_sb_l > 0) \</span><br><span style="color: hsl(120, 100%, 40%);">+                   (STRBUF).chars_needed += _sb_l; \</span><br><span>    } while(0)</span><br><span> </span><br><span> /*! Shortcut for OSMO_STRBUF_APPEND() invocation using snprintf().</span><br><span>@@ -237,6 +237,29 @@</span><br><span> #define OSMO_STRBUF_PRINTF(STRBUF, fmt, args...) \</span><br><span>    OSMO_STRBUF_APPEND(STRBUF, snprintf, fmt, ##args)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! Like OSMO_STRBUF_APPEND(), but for function signatures that return the char* buffer instead of a length.</span><br><span style="color: hsl(120, 100%, 40%);">+ * When using this function, the final STRBUF.chars_needed may not reflect the actual number of characters needed, since</span><br><span style="color: hsl(120, 100%, 40%);">+ * that number cannot be obtained from this kind of function signature.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[inout] STRBUF  A struct osmo_strbuf instance.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] func  A function with a signature of char *func(char *dst, size_t dst_len [, args]) where</span><br><span style="color: hsl(120, 100%, 40%);">+ *                  the returned string is always written to dst.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] args  Arguments passed to func, if any.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#define OSMO_STRBUF_APPEND_NOLEN(STRBUF, func, args...) do { \</span><br><span style="color: hsl(120, 100%, 40%);">+               if (!(STRBUF).pos) \</span><br><span style="color: hsl(120, 100%, 40%);">+                  (STRBUF).pos = (STRBUF).buf; \</span><br><span style="color: hsl(120, 100%, 40%);">+                size_t _sb_remain = (STRBUF).buf ? (STRBUF).len - ((STRBUF).pos - (STRBUF).buf) : 0; \</span><br><span style="color: hsl(120, 100%, 40%);">+                if (_sb_remain) { \</span><br><span style="color: hsl(120, 100%, 40%);">+                   func((STRBUF).pos, _sb_remain, ##args); \</span><br><span style="color: hsl(120, 100%, 40%);">+             } \</span><br><span style="color: hsl(120, 100%, 40%);">+           size_t _sb_l = (STRBUF).pos ? strnlen((STRBUF).pos, _sb_remain) : 0; \</span><br><span style="color: hsl(120, 100%, 40%);">+                if (_sb_l > _sb_remain) \</span><br><span style="color: hsl(120, 100%, 40%);">+                  (STRBUF).pos = (STRBUF).buf + (STRBUF).len; \</span><br><span style="color: hsl(120, 100%, 40%);">+         else if ((STRBUF).pos) \</span><br><span style="color: hsl(120, 100%, 40%);">+                      (STRBUF).pos += _sb_l; \</span><br><span style="color: hsl(120, 100%, 40%);">+              (STRBUF).chars_needed += _sb_l; \</span><br><span style="color: hsl(120, 100%, 40%);">+     } while(0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> bool osmo_str_startswith(const char *str, const char *startswith_str);</span><br><span> </span><br><span> /*! @} */</span><br><span>diff --git a/tests/utils/utils_test.c b/tests/utils/utils_test.c</span><br><span>index 211b4d1..223f67d 100644</span><br><span>--- a/tests/utils/utils_test.c</span><br><span>+++ b/tests/utils/utils_test.c</span><br><span>@@ -1014,6 +1014,23 @@</span><br><span>        printf("(need %d chars, had size=63) %s\n", rc, buf);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void strbuf_test_nolen()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ char buf[20];</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_strbuf sb = { .buf = buf, .len = sizeof(buf) };</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t ubits[] = {0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0};</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("\n%s\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_STRBUF_APPEND_NOLEN(sb, osmo_ubit_dump_buf, ubits, sizeof(ubits));</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("%zu: %s (need=%zu)\n", sb.len, buf, sb.chars_needed);</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_STRBUF_APPEND_NOLEN(sb, osmo_ubit_dump_buf, ubits, sizeof(ubits));</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("more: %s (need=%zu)\n", buf, sb.chars_needed);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    sb = (struct osmo_strbuf){ .buf = buf, .len = 10 };</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_STRBUF_APPEND_NOLEN(sb, osmo_ubit_dump_buf, ubits, sizeof(ubits));</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("%zu: %s (need=%zu)\n", sb.len, buf, sb.chars_needed);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void startswith_test_str(const char *str, const char *startswith_str, bool expect_rc)</span><br><span> {</span><br><span>    bool rc = osmo_str_startswith(str, startswith_str);</span><br><span>@@ -1059,6 +1076,7 @@</span><br><span>  osmo_sockaddr_to_str_and_uint_test();</span><br><span>        osmo_str_tolowupper_test();</span><br><span>  strbuf_test();</span><br><span style="color: hsl(120, 100%, 40%);">+        strbuf_test_nolen();</span><br><span>         startswith_test();</span><br><span>   return 0;</span><br><span> }</span><br><span>diff --git a/tests/utils/utils_test.ok b/tests/utils/utils_test.ok</span><br><span>index 5783eb1..587c6f0 100644</span><br><span>--- a/tests/utils/utils_test.ok</span><br><span>+++ b/tests/utils/utils_test.ok</span><br><span>@@ -341,6 +341,11 @@</span><br><span> T minus 10 9 8 7 6 5 4 3 2 1 ... Lift off! -- T minus 10 9 8 7 6 5 4 3 2 1 ... Lift off! -- T minus 10 9 8 7 6 5 4 3 2 1 ... Lift off!</span><br><span> (need 134 chars, had size=63) T minus 10 9 8 7 6 5 4 3 2 1 ... Lift off! -- T minus 10 9 8 7</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+strbuf_test_nolen</span><br><span style="color: hsl(120, 100%, 40%);">+20: 0001011100101010 (need=16)</span><br><span style="color: hsl(120, 100%, 40%);">+more: 0001011100101010000 (need=19)</span><br><span style="color: hsl(120, 100%, 40%);">+10: 000101110 (need=9)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> startswith_test()</span><br><span> osmo_str_startswith(NULL, NULL) == true</span><br><span> osmo_str_startswith("", NULL) == true</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/13594">change 13594</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.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.osmocom.org/13594"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I108cadf72deb3a3bcab9a07e50572d9da1ab0359 </div>
<div style="display:none"> Gerrit-Change-Number: 13594 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>