Add DStr sprintf
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#define UC_DSTR_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -134,6 +135,12 @@ size_t uc_dstr_replace(struct DStr *str, char f, char r);
|
||||
*/
|
||||
void uc_dstr_trim(struct DStr *str);
|
||||
|
||||
/** Append formatted string (just as sprintf)*/
|
||||
int uc_dstr_sprintf(struct DStr *str, const char *fmt, ...) __attribute__((format(printf,2,3)));
|
||||
|
||||
/** va_list variant */
|
||||
int uc_dstr_vsprintf(struct DStr *str, const char *fmt, va_list ap_)__attribute__((format(printf,2,0)));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
+54
-1
@@ -1,5 +1,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "ucore/dstr.h"
|
||||
#include "ucore/utils.h"
|
||||
|
||||
@@ -26,7 +28,7 @@ int uc_dstr_ensure(struct DStr *str, size_t len)
|
||||
//allocate a minimum no. of bytes, and one
|
||||
//additional for the common case of nul terminating
|
||||
//the string
|
||||
size_t new_len = str->len + UC_MAX(7U, len) + 1;
|
||||
size_t new_len = UC_MAX(7U, len) + 1;
|
||||
char *new_str = realloc(str->str, new_len);
|
||||
|
||||
if (new_str == NULL) {
|
||||
@@ -204,4 +206,55 @@ void uc_dstr_trim(struct DStr *str)
|
||||
}
|
||||
}
|
||||
|
||||
int uc_dstr_sprintf(struct DStr *str, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int rc;
|
||||
|
||||
va_start(ap, fmt);
|
||||
rc = uc_dstr_vsprintf(str, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int uc_dstr_vsprintf(struct DStr *str, const char *fmt, va_list ap_)
|
||||
{
|
||||
va_list ap;
|
||||
int rc;
|
||||
int available;
|
||||
int needed;
|
||||
|
||||
rc = uc_dstr_ensure(str, str->len + 1);
|
||||
if (rc != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
available = uc_dstr_available(str);
|
||||
|
||||
va_copy(ap, ap_);
|
||||
needed = vsnprintf(str->str + str->len, available, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (needed <= 0) {
|
||||
return needed;
|
||||
}
|
||||
|
||||
if (needed >= available) {
|
||||
rc = uc_dstr_ensure(str, str->len + needed);
|
||||
if (rc != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
available = uc_dstr_available(str);
|
||||
|
||||
va_copy(ap, ap_);
|
||||
needed = vsnprintf(str->str + str->len, available, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
str->len += needed;
|
||||
|
||||
return needed;
|
||||
}
|
||||
|
||||
|
||||
+19
-1
@@ -31,7 +31,7 @@ START_TEST (test_dstr_basics)
|
||||
ck_assert_str_eq(uc_dstr_str(&str), "");
|
||||
|
||||
uc_dstr_reset(&str);
|
||||
ck_assert_int_ge(uc_dstr_available(&str), 0);
|
||||
ck_assert_int_gt(uc_dstr_available(&str), 0);
|
||||
|
||||
s = uc_dstr_put(&str, 2);
|
||||
fail_if(s == NULL);
|
||||
@@ -123,6 +123,23 @@ START_TEST (test_dstr_filter)
|
||||
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_dstr_sprintf)
|
||||
struct DStr str;
|
||||
size_t rc;
|
||||
|
||||
uc_dstr_init(&str);
|
||||
rc = uc_dstr_sprintf(&str, "%d-%d-%d", 1, 2, 3);
|
||||
ck_assert_int_gt(rc, 0);
|
||||
ck_assert_str_eq(uc_dstr_str(&str), "1-2-3");
|
||||
|
||||
rc = uc_dstr_sprintf(&str, " Another, bigger %s.", "string");
|
||||
ck_assert_int_gt(rc, 0);
|
||||
ck_assert_str_eq(uc_dstr_str(&str), "1-2-3 Another, bigger string.");
|
||||
|
||||
uc_dstr_destroy(&str);
|
||||
|
||||
END_TEST
|
||||
|
||||
Suite *dstr_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("dstr");
|
||||
@@ -132,6 +149,7 @@ Suite *dstr_suite(void)
|
||||
tcase_add_test(tc, test_dstr_trim);
|
||||
tcase_add_test(tc, test_dstr_replace);
|
||||
tcase_add_test(tc, test_dstr_filter);
|
||||
tcase_add_test(tc, test_dstr_sprintf);
|
||||
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user