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;
 }