rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

commit 9820a8b9d226fcdbd8cec92b68aecadde1b81405
parent c5fef4955facb3aca17176f5e0df090ecf9108a4
Author: vaplv <vaplv@free.fr>
Date:   Fri,  3 Jul 2020 12:37:38 +0200

Add and test the str_printf function

Setup the str content from the string formatted following the "printf"
syntax.

Diffstat:
Msrc/str.c | 34+++++++++++++++++++++++++++++++++-
Msrc/str.h | 10++++++++++
Msrc/test_str.c | 11+++++++++++
3 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/src/str.c b/src/str.c @@ -13,7 +13,11 @@ * You should have received a copy of the GNU Lesser General Public License * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */ +#define _POSIX_C_SOURCE 200112L /* vsnprintf support */ +#include "io_c99.h" #include "str.h" + +#include <stdarg.h> #include <string.h> /******************************************************************************* @@ -156,7 +160,7 @@ str_append_char(struct str* str, const char ch) { size_t len = 0; res_T res = RES_OK; - ASSERT( str ); + ASSERT(str); if(ch == '\0') return RES_OK; @@ -176,3 +180,31 @@ str_reserve(struct str* str, const size_t capacity) return ensure_allocated(str, capacity / sizeof(char), 1); } + +res_T +str_printf(struct str* str, const char* fmt, ...) +{ + va_list ap; + size_t len; + res_T res = RES_OK; + ASSERT(str && fmt); + + va_start(ap, fmt); + len = (size_t)vsnprintf(str->cstr, str->allocated, fmt, ap); + va_end(ap); + + if(len >= str->allocated) { + res = ensure_allocated(str, len + 1/* Null char */, 0); + if(res != RES_OK) goto error; + + va_start(ap, fmt); + len = (size_t)vsnprintf(str->cstr, str->allocated, fmt, ap); + va_end(ap); + CHK(len < str->allocated); + } + +exit: + return res; +error: + goto exit; +} diff --git a/src/str.h b/src/str.h @@ -105,6 +105,16 @@ RSYS_API res_T str_append(struct str* str, const char* cstr); RSYS_API res_T str_append_char(struct str* str, const char ch); RSYS_API res_T str_reserve(struct str* str, const size_t capacity); +RSYS_API res_T +str_printf + (struct str* str, + const char* fmt, + ...) +#ifdef COMPILER_GCC + __attribute__((format(printf, 2, 3))) +#endif +; + END_DECLS static INLINE res_T diff --git a/src/test_str.c b/src/test_str.c @@ -139,6 +139,17 @@ main(int argc, char** argv) str_release(&str); str_init(&allocator_proxy, &str); + CHK(str_printf(&str, "Hello world!") == RES_OK); + CHK(!strcmp(str_cget(&str), "Hello world!")); + CHK(str_printf(&str, "XARR-QRRC VA GUR QRNQ") == RES_OK); + CHK(!strcmp(str_cget(&str), "XARR-QRRC VA GUR QRNQ")); + CHK(str_printf(&str, "Rcvfbqr %d, GUR FUBERF BS URYY", 2) == RES_OK); + CHK(!strcmp(str_cget(&str), "Rcvfbqr 2, GUR FUBERF BS URYY")); + CHK(str_printf(&str, "%s:%lu:%s", __FILE__, 0xDECAFBADlu,__FILE__) == RES_OK); + CHK(!strcmp(str_cget(&str), __FILE__":3737844653:"__FILE__)); + str_release(&str); + + str_init(&allocator_proxy, &str); CHK(str_set(&str, "abcd") == RES_OK); CHK(str_len(&str) == 4); str_get(&str)[3] = '\0';