rsys

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

commit 0abee385cd516bb0cbcd784affddb0d445911683
parent b35ce6ae710b2a5e16f7125764591d132c2064f2
Author: vaplv <vaplv@free.fr>
Date:   Mon, 20 Jul 2020 13:05:28 +0200

Add and test the str_vprintf and str_append_[v]printf functions

Diffstat:
Msrc/str.c | 50++++++++++++++++++++++++++++++++++++++++++--------
Msrc/str.h | 24++++++++++++++++++++++++
Msrc/test_str.c | 45+++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 111 insertions(+), 8 deletions(-)

diff --git a/src/str.c b/src/str.c @@ -17,7 +17,6 @@ #include "io_c99.h" #include "str.h" -#include <stdarg.h> #include <string.h> /******************************************************************************* @@ -185,22 +184,57 @@ 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); + res = str_vprintf(str, fmt, ap); + va_end(ap); + return res; +} +res_T +str_append_printf(struct str* str, const char* fmt, ...) +{ + va_list ap; + res_T res = RES_OK; + ASSERT(str && fmt); va_start(ap, fmt); - len = (size_t)vsnprintf(str->cstr, str->allocated, fmt, ap); + res = str_append_vprintf(str, fmt, ap); + va_end(ap); + return res; +} + +res_T +str_vprintf(struct str* str, const char* fmt, va_list vargs_list) +{ + ASSERT(str && fmt); + str_clear(str); + return str_append_vprintf(str, fmt, vargs_list); +} + +res_T +str_append_vprintf(struct str* str, const char* fmt, va_list vargs_list) +{ + va_list ap; + size_t flen; /* Length of the formatted message */ + size_t slen; /* Length of the string */ + res_T res = RES_OK; + ASSERT(str && fmt); + + slen = str_len(str); + + VA_COPY(ap, vargs_list); + flen = (size_t)vsnprintf(str->cstr + slen, str->allocated - slen, fmt, ap); va_end(ap); - if(len >= str->allocated) { - res = ensure_allocated(str, len + 1/* Null char */, 0); + if(slen + flen >= str->allocated) { + res = ensure_allocated(str, slen + flen + 1/* Null char */, 1); if(res != RES_OK) goto error; - va_start(ap, fmt); - len = (size_t)vsnprintf(str->cstr, str->allocated, fmt, ap); + VA_COPY(ap, vargs_list); + flen = (size_t)vsnprintf(str->cstr + slen, str->allocated - slen, fmt, ap); va_end(ap); - CHK(len < str->allocated); + CHK(slen + flen < str->allocated); } exit: diff --git a/src/str.h b/src/str.h @@ -19,6 +19,8 @@ #include "hash.h" #include "mem_allocator.h" #include "rsys.h" + +#include <stdarg.h> #include <string.h> struct str { @@ -115,6 +117,28 @@ str_printf #endif ; +RSYS_API res_T +str_append_printf + (struct str* str, + const char* fmt, + ...) +#ifdef COMPILER_GCC + __attribute__((format(printf, 2, 3))) +#endif +; + +RSYS_API res_T +str_vprintf + (struct str* str, + const char* fmt, + va_list vargs_list); + +RSYS_API res_T +str_append_vprintf + (struct str* str, + const char* fmt, + va_list vargs_list); + END_DECLS static INLINE res_T diff --git a/src/test_str.c b/src/test_str.c @@ -15,8 +15,34 @@ #include "str.h" #include "test_utils.h" +#include <stdarg.h> #include <string.h> +#ifdef COMPILER_GCC +__attribute__((format(printf, 2, 3))) +#endif +static void +chk_vprintf(struct str* str, const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + CHK(str_vprintf(str, fmt, ap) == RES_OK); + va_end(ap); +} + +#ifdef COMPILER_GCC +__attribute__((format(printf, 2, 3))) +#endif +static void +chk_append_vprintf(struct str* str, const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + CHK(str_append_vprintf(str, fmt, ap) == RES_OK); + va_end(ap); +} + + int main(int argc, char** argv) { @@ -150,6 +176,25 @@ main(int argc, char** argv) str_release(&str); str_init(&allocator_proxy, &str); + CHK(str_printf(&str, "Hello, ") == RES_OK); + CHK(str_append_printf(&str, "world!") == RES_OK); + CHK(!strcmp(str_cget(&str), "Hello, world!")); + CHK(str_printf(&str, "%s:%lu", __FILE__, 0xDECAFBADlu) == RES_OK); + CHK(str_append_printf(&str, ":%s", __FILE__) == RES_OK); + CHK(!strcmp(str_cget(&str), __FILE__":3737844653:"__FILE__)); + chk_vprintf(&str, "You should have received a copy of the %s %s %d", + "GNU", "Lesser General Public License", 3); + CHK(!strcmp(str_cget(&str), + "You should have received a copy of the " + "GNU Lesser General Public License 3")); + chk_append_vprintf(&str, " along with the %s library. If not, see %c%s%c.", + "RSys", '<', "http://www.gnu.org/licenses/", '>'); + CHK(!strcmp(str_cget(&str), + "You should have received a copy of the GNU Lesser General Public License 3 " + "along with the RSys library. If not, see <http://www.gnu.org/licenses/>.")); + 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';