Add DStr sprintf
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
#define UC_DSTR_H_
|
#define UC_DSTR_H_
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+54
-1
@@ -1,5 +1,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include "ucore/dstr.h"
|
#include "ucore/dstr.h"
|
||||||
#include "ucore/utils.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
|
//allocate a minimum no. of bytes, and one
|
||||||
//additional for the common case of nul terminating
|
//additional for the common case of nul terminating
|
||||||
//the string
|
//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);
|
char *new_str = realloc(str->str, new_len);
|
||||||
|
|
||||||
if (new_str == NULL) {
|
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), "");
|
ck_assert_str_eq(uc_dstr_str(&str), "");
|
||||||
|
|
||||||
uc_dstr_reset(&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);
|
s = uc_dstr_put(&str, 2);
|
||||||
fail_if(s == NULL);
|
fail_if(s == NULL);
|
||||||
@@ -123,6 +123,23 @@ START_TEST (test_dstr_filter)
|
|||||||
|
|
||||||
END_TEST
|
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 *dstr_suite(void)
|
||||||
{
|
{
|
||||||
Suite *s = suite_create("dstr");
|
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_trim);
|
||||||
tcase_add_test(tc, test_dstr_replace);
|
tcase_add_test(tc, test_dstr_replace);
|
||||||
tcase_add_test(tc, test_dstr_filter);
|
tcase_add_test(tc, test_dstr_filter);
|
||||||
|
tcase_add_test(tc, test_dstr_sprintf);
|
||||||
|
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user