util: add osmo_strbuf macros to manipulate the strbuf tail

Upcoming patch adopts osmo_strbuf in logging.c, which sometimes needs to
steal and re-add trailing newline characters, and also needs to let
ctime_r() write to the buffer before updating the osmo_strbuf state.

Related: OS#6284
Related: Ib577a5e0d7450ce93ff21f37ba3262704cbf4752
Change-Id: I997707c328eab3ffa00a78fdb9a0a2cbe18404b4
diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h
index 2a3670b..b6e67e2 100644
--- a/include/osmocom/core/utils.h
+++ b/include/osmocom/core/utils.h
@@ -284,6 +284,12 @@
 /*! Return remaining space for characters and terminating nul in the given struct osmo_strbuf. */
 #define OSMO_STRBUF_REMAIN(STRBUF) ((STRBUF).buf ? (STRBUF).len - ((STRBUF).pos - (STRBUF).buf) : 0)
 
+/*! Return number of actual characters contained in struct osmo_strbuf (without terminating nul). */
+#define OSMO_STRBUF_CHAR_COUNT(STRBUF) ((STRBUF).buf && ((STRBUF).pos > (STRBUF).buf) ? \
+					OSMO_MIN((STRBUF).pos - (STRBUF).buf, \
+						 (STRBUF).len - 1) \
+					: 0)
+
 /*! Like OSMO_STRBUF_APPEND(), but for function signatures that return the char* buffer instead of a length.
  * When using this function, the final STRBUF.chars_needed may not reflect the actual number of characters needed, since
  * that number cannot be obtained from this kind of function signature.
@@ -307,6 +313,16 @@
 		(STRBUF).chars_needed += _sb_l; \
 	} while(0)
 
+void osmo_strbuf_drop_tail(struct osmo_strbuf *sb, size_t n_chars);
+/* Convenience macro. struct osmo_strbuf are typically static to a function scope. Avoid having to type '&', same as
+ * with all the other OSMO_STRBUF_* API. */
+#define OSMO_STRBUF_DROP_TAIL(STRBUF, N_CHARS) osmo_strbuf_drop_tail(&(STRBUF), N_CHARS)
+
+void osmo_strbuf_added_tail(struct osmo_strbuf *sb, size_t n_chars);
+/* Convenience macro. struct osmo_strbuf are typically static to a function scope. Avoid having to type '&', same as
+ * with all the other OSMO_STRBUF_* API. */
+#define OSMO_STRBUF_ADDED_TAIL(STRBUF, N_CHARS) osmo_strbuf_added_tail(&(STRBUF), N_CHARS)
+
 bool osmo_str_startswith(const char *str, const char *startswith_str);
 
 int osmo_float_str_to_int(int64_t *val, const char *str, unsigned int precision);