diff options
| author | Neels Hofmeyr <neels@hofmeyr.de> | 2019-04-11 07:16:02 +0200 | 
|---|---|---|
| committer | Neels Hofmeyr <neels@hofmeyr.de> | 2019-04-11 07:40:25 +0200 | 
| commit | 8531d6695f7363e5fa24141c53253e699d99ca0a (patch) | |
| tree | 0c89e7ee2c6dc6767ca512ec6537579fd1c9df22 | |
| parent | d79ccc65f7134839a6d00f0eb70f43c2b614e9c8 (diff) | |
tweak OSMO_STRBUF_APPEND(), add OSMO_STRBUF_APPEND_NOLEN()
In OSMO_STRBUF_APPEND, use local variable names that are less likely to shadow
other local variables: prefix with _sb_.
In OSMO_STRBUF_APPEND, add a check to add to .pos only if it is not NULL.
Add OSMO_STRBUF_APPEND_NOLEN(), which works for function signatures that don't
return a length. This is useful for any osmo_*_buf() string writing functions,
so that these write directly to the strbuf.
Change-Id: I108cadf72deb3a3bcab9a07e50572d9da1ab0359
| -rw-r--r-- | include/osmocom/core/utils.h | 37 | ||||
| -rw-r--r-- | tests/utils/utils_test.c | 18 | ||||
| -rw-r--r-- | tests/utils/utils_test.ok | 5 | 
3 files changed, 53 insertions, 7 deletions
diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h index 474e36c4..f13c1e48 100644 --- a/include/osmocom/core/utils.h +++ b/include/osmocom/core/utils.h @@ -205,14 +205,14 @@ struct osmo_strbuf {  #define OSMO_STRBUF_APPEND(STRBUF, func, args...) do { \  		if (!(STRBUF).pos) \  			(STRBUF).pos = (STRBUF).buf; \ -		size_t remain = (STRBUF).buf ? (STRBUF).len - ((STRBUF).pos - (STRBUF).buf) : 0; \ -		int l = func((STRBUF).pos, remain, ##args); \ -		if (l < 0 || l > remain) \ +		size_t _sb_remain = (STRBUF).buf ? (STRBUF).len - ((STRBUF).pos - (STRBUF).buf) : 0; \ +		int _sb_l = func((STRBUF).pos, _sb_remain, ##args); \ +		if (_sb_l < 0 || _sb_l > _sb_remain) \  			(STRBUF).pos = (STRBUF).buf + (STRBUF).len; \ -		else \ -			(STRBUF).pos += l; \ -		if (l > 0) \ -			(STRBUF).chars_needed += l; \ +		else if ((STRBUF).pos) \ +			(STRBUF).pos += _sb_l; \ +		if (_sb_l > 0) \ +			(STRBUF).chars_needed += _sb_l; \  	} while(0)  /*! Shortcut for OSMO_STRBUF_APPEND() invocation using snprintf(). @@ -237,6 +237,29 @@ struct osmo_strbuf {  #define OSMO_STRBUF_PRINTF(STRBUF, fmt, args...) \  	OSMO_STRBUF_APPEND(STRBUF, snprintf, fmt, ##args) +/*! 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. + * \param[inout] STRBUF  A struct osmo_strbuf instance. + * \param[in] func  A function with a signature of char *func(char *dst, size_t dst_len [, args]) where + *                  the returned string is always written to dst. + * \param[in] args  Arguments passed to func, if any. + */ +#define OSMO_STRBUF_APPEND_NOLEN(STRBUF, func, args...) do { \ +		if (!(STRBUF).pos) \ +			(STRBUF).pos = (STRBUF).buf; \ +		size_t _sb_remain = (STRBUF).buf ? (STRBUF).len - ((STRBUF).pos - (STRBUF).buf) : 0; \ +		if (_sb_remain) { \ +			func((STRBUF).pos, _sb_remain, ##args); \ +		} \ +		size_t _sb_l = (STRBUF).pos ? strnlen((STRBUF).pos, _sb_remain) : 0; \ +		if (_sb_l > _sb_remain) \ +			(STRBUF).pos = (STRBUF).buf + (STRBUF).len; \ +		else if ((STRBUF).pos) \ +			(STRBUF).pos += _sb_l; \ +		(STRBUF).chars_needed += _sb_l; \ +	} while(0) +  bool osmo_str_startswith(const char *str, const char *startswith_str);  /*! @} */ diff --git a/tests/utils/utils_test.c b/tests/utils/utils_test.c index 211b4d1a..223f67d2 100644 --- a/tests/utils/utils_test.c +++ b/tests/utils/utils_test.c @@ -1014,6 +1014,23 @@ void strbuf_test()  	printf("(need %d chars, had size=63) %s\n", rc, buf);  } +void strbuf_test_nolen() +{ +	char buf[20]; +	struct osmo_strbuf sb = { .buf = buf, .len = sizeof(buf) }; +	uint8_t ubits[] = {0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0}; +	printf("\n%s\n", __func__); + +	OSMO_STRBUF_APPEND_NOLEN(sb, osmo_ubit_dump_buf, ubits, sizeof(ubits)); +	printf("%zu: %s (need=%zu)\n", sb.len, buf, sb.chars_needed); +	OSMO_STRBUF_APPEND_NOLEN(sb, osmo_ubit_dump_buf, ubits, sizeof(ubits)); +	printf("more: %s (need=%zu)\n", buf, sb.chars_needed); + +	sb = (struct osmo_strbuf){ .buf = buf, .len = 10 }; +	OSMO_STRBUF_APPEND_NOLEN(sb, osmo_ubit_dump_buf, ubits, sizeof(ubits)); +	printf("%zu: %s (need=%zu)\n", sb.len, buf, sb.chars_needed); +} +  static void startswith_test_str(const char *str, const char *startswith_str, bool expect_rc)  {  	bool rc = osmo_str_startswith(str, startswith_str); @@ -1059,6 +1076,7 @@ int main(int argc, char **argv)  	osmo_sockaddr_to_str_and_uint_test();  	osmo_str_tolowupper_test();  	strbuf_test(); +	strbuf_test_nolen();  	startswith_test();  	return 0;  } diff --git a/tests/utils/utils_test.ok b/tests/utils/utils_test.ok index 5783eb16..587c6f09 100644 --- a/tests/utils/utils_test.ok +++ b/tests/utils/utils_test.ok @@ -341,6 +341,11 @@ cascade:  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!  (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 +strbuf_test_nolen +20: 0001011100101010 (need=16) +more: 0001011100101010000 (need=19) +10: 000101110 (need=9) +  startswith_test()  osmo_str_startswith(NULL, NULL) == true  osmo_str_startswith("", NULL) == true  | 
