Mercurial > lbo > hg > ylisp
changeset 39:9de50050f36f
base/str: Add copy and new methods for ystr_t
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Wed, 21 Aug 2019 13:06:45 +0200 |
parents | c74b95dafa53 |
children | 63b0bf003bb9 |
files | src/base/str.c src/base/str.h src/base/str_test.c |
diffstat | 3 files changed, 48 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/src/base/str.c Wed Aug 21 13:06:10 2019 +0200 +++ b/src/base/str.c Wed Aug 21 13:06:45 2019 +0200 @@ -7,6 +7,12 @@ static inline bool ystr_is_inline(ystr_t *s) { return 0 == s->inner.big.size; } +ystr_t ystr_new(const char* src) { + ystr_t str; + ystr_init(&str, src); + return str; +} + void ystr_init(ystr_t *s, const char *src) { memset(s, 0, sizeof(ystr_t)); ystr_set(s, src); @@ -153,6 +159,17 @@ yvec_push_multi(&s1->inner.big, ystr_str(s2), ystr_len(s2) + 1); } +void ystr_copy(ystr_t* src, ystr_t* dst) { + if (dst == NULL || src == NULL) + return; + ystr_destroy(dst); + if (ystr_is_inline(src)) { + memcpy(dst, src, sizeof(ystr_t)); + return; + } + yvec_copy(&src->inner.big, &dst->inner.big); +} + #define YSTR_BUILD_BUF_SIZE 128 void ystr_build(ystr_t *s, const char *fmt, ...) { @@ -172,6 +189,7 @@ va_end(args); ystr_t fmtd; + ystr_init(&fmtd, NULL); ystr_set_owned(&fmtd, buf2); ystr_append(s, &fmtd); ystr_destroy(&fmtd);
--- a/src/base/str.h Wed Aug 21 13:06:10 2019 +0200 +++ b/src/base/str.h Wed Aug 21 13:06:45 2019 +0200 @@ -29,6 +29,11 @@ } ystr_t; /** + * @brief Create a new string and return it. It must be freed with `ystr_destroy()` after use. + */ +ystr_t ystr_new(const char* src); + +/** * @brief Initialize a `ystr_t` with `src`, which can be `NULL`. The string * contents are copied, and `src` ownership stays with the caller. */ @@ -108,6 +113,11 @@ void ystr_resize(ystr_t *s, size_t new); /** + * @brief Create a copy of `src` in `dst`, potentially freeing dst before copying. + */ +void ystr_copy(ystr_t* src, ystr_t* dst); + +/** * @brief Append a C string to string, with possible formatting directives like * printf. */
--- a/src/base/str_test.c Wed Aug 21 13:06:10 2019 +0200 +++ b/src/base/str_test.c Wed Aug 21 13:06:45 2019 +0200 @@ -5,13 +5,11 @@ #include <stdio.h> void test_inline_string(void) { - ystr_t str, str2; + ystr_t str = ystr_new("short"), str2 = ystr_new("looooooooooooooooooooooooooong"); - ystr_init(&str, "short"); assert(0 == str.inner.big.size); assert(0 == strcmp("short", ystr_str(&str))); - ystr_init(&str2, "looooooooooooooooooooooooooong"); assert(0 != str2.inner.big.size); assert(0 == strcmp("looooooooooooooooooooooooooong", ystr_str(&str2))); @@ -164,6 +162,24 @@ ystr_destroy(&s); } +void test_string_copy(void) { + ystr_t s1, s2; + ystr_init(&s1, "hello"); + ystr_init(&s2, NULL); + ystr_copy(&s1, &s2); + assert(0 == ystr_cmp(&s1, &s2)); + + + const char* longstr = "a long string that is not inlined"; + ystr_set_owned(&s1, strdup(longstr)); + ystr_copy(&s1, &s2); + assert(0 == ystr_cmp(&s1, &s2)); + assert(0 == ystr_cmp_str(&s2, longstr)); + + ystr_destroy(&s1); + ystr_destroy(&s2); +} + int main(int argc, char** argv) { // Use `make valgrind` to check that all memory is freed by str_test. test_inline_string(); @@ -175,5 +191,6 @@ test_str_build(); test_string_split(); test_string_resize(); + test_string_copy(); return 0; }