From 28ac9ed8c84efd52fc18fc7251a50924793e4b71 Mon Sep 17 00:00:00 2001
From: Abdelrahman <said.abdelrahman89@gmail.com>
Date: Sat, 22 Feb 2025 13:39:03 +0000
Subject: [PATCH] Modify Str8 substr functionality

---
 src/core/strings/str8/str8.c |  40 +++++++++++---
 src/core/strings/str8/str8.h |   3 +-
 tests/str8/test_str8.c       | 103 +++++++++++++++++++++++------------
 tests/str8/test_str8.h       |   3 +-
 tests/wapptest.c             |   3 +-
 5 files changed, 107 insertions(+), 45 deletions(-)

diff --git a/src/core/strings/str8/str8.c b/src/core/strings/str8/str8.c
index 00027fd..24cecd5 100644
--- a/src/core/strings/str8/str8.c
+++ b/src/core/strings/str8/str8.c
@@ -71,6 +71,32 @@ RETURN_ALLOC_STR8:
   return output;
 }
 
+Str8 *wapp_str8_alloc_substr(const Allocator *allocator, Str8RO *str, u64 start, u64 end) {
+  Str8 *output = NULL;
+  if (!allocator || !str) {
+    goto RETURN_ALLOC_SUBSTR;
+  }
+
+  if (start >= str->size || start >= end) {
+    goto RETURN_ALLOC_SUBSTR;
+  }
+
+  if (end > str->size) {
+    end = str->size;
+  }
+
+  output = wapp_str8_alloc_buf(allocator, str->capacity);
+  if (!output) {
+    goto RETURN_ALLOC_SUBSTR;
+  }
+
+  output->size = end - start;
+  memcpy(output->buf, str->buf + start, output->size);
+
+RETURN_ALLOC_SUBSTR:
+  return output;
+}
+
 c8 wapp_str8_get(const Str8 *str, u64 index) {
   if (index >= str->size) {
     return '\0';
@@ -103,7 +129,7 @@ bool wapp_str8_equal_to_count(Str8RO* s1, Str8RO* s2, u64 count) {
     return memcmp(s1->buf, s2->buf, count) == 0;
 }
 
-Str8RO wapp_str8_substr(Str8RO *str, u64 start, u64 end) {
+Str8 wapp_str8_slice(Str8RO *str, u64 start, u64 end) {
   if (start >= str->size || start >= end) {
     return (Str8RO){0};
   }
@@ -268,8 +294,8 @@ Str8List *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8
       break;
     }
 
-    Str8RO before = wapp_str8_substr(str, start, start + end);
-    Str8RO after  = wapp_str8_substr(str, start + end + delimiter->size, str->size);
+    Str8RO before = wapp_str8_slice(str, start, start + end);
+    Str8RO after  = wapp_str8_slice(str, start + end + delimiter->size, str->size);
 
     before_str     = wapp_str8_alloc_str8(allocator, &before);
     Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node));
@@ -285,7 +311,7 @@ Str8List *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8
     ++splits;
   }
 
-  Str8RO last    = wapp_str8_substr(str, start, str->size);
+  Str8RO last    = wapp_str8_slice(str, start, str->size);
   rest           = wapp_str8_alloc_str8(allocator, &last);
   Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node));
   if (node) {
@@ -325,8 +351,8 @@ Str8List *wapp_str8_rsplit_with_max(const Allocator *allocator, Str8RO *str, Str
       break;
     }
 
-    Str8RO before = wapp_str8_substr(rest, 0, end);
-    Str8RO after  = wapp_str8_substr(rest, end + delimiter->size, str->size);
+    Str8RO before = wapp_str8_slice(rest, 0, end);
+    Str8RO after  = wapp_str8_slice(rest, end + delimiter->size, str->size);
 
     after_str     = wapp_str8_alloc_str8(allocator, &after);
     Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node));
@@ -341,7 +367,7 @@ Str8List *wapp_str8_rsplit_with_max(const Allocator *allocator, Str8RO *str, Str
     ++splits;
   }
 
-  Str8RO last    = wapp_str8_substr(str, 0, rest->size);
+  Str8RO last    = wapp_str8_slice(str, 0, rest->size);
   rest           = wapp_str8_alloc_str8(allocator, &last);
   Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node));
   if (node) {
diff --git a/src/core/strings/str8/str8.h b/src/core/strings/str8/str8.h
index 39480a4..d0a9a49 100644
--- a/src/core/strings/str8/str8.h
+++ b/src/core/strings/str8/str8.h
@@ -60,6 +60,7 @@ struct str8_list {
 Str8 *wapp_str8_alloc_buf(const Allocator *allocator, u64 capacity);
 Str8 *wapp_str8_alloc_cstr(const Allocator *allocator, const char *str);
 Str8 *wapp_str8_alloc_str8(const Allocator *allocator, Str8RO *str);
+Str8 *wapp_str8_alloc_substr(const Allocator *allocator, Str8RO *str, u64 start, u64 end);
 
 /**
  * Str8 utilities
@@ -68,7 +69,7 @@ c8     wapp_str8_get(Str8RO *str, u64 index);
 void   wapp_str8_set(Str8 *str, u64 index, c8 c);
 bool   wapp_str8_equal(Str8RO *s1, Str8RO *s2);
 bool   wapp_str8_equal_to_count(Str8RO* s1, Str8RO* s2, u64 count);
-Str8RO wapp_str8_substr(Str8RO *str, u64 start, u64 end);
+Str8   wapp_str8_slice(Str8RO *str, u64 start, u64 end);
 Str8   *wapp_str8_concat(const Allocator *allocator, Str8 *dst, Str8RO *src);
 void   wapp_str8_concat_capped(Str8 *dst, Str8RO *src);
 void   wapp_str8_copy_cstr_capped(Str8 *dst, const char *src);
diff --git a/tests/str8/test_str8.c b/tests/str8/test_str8.c
index 0a605a8..c7380a1 100644
--- a/tests/str8/test_str8.c
+++ b/tests/str8/test_str8.c
@@ -82,14 +82,27 @@ TestFuncResult test_str8_buf(void) {
 
 TestFuncResult test_str8_alloc_buf(void) {
   bool result;
-  Allocator allocator = wapp_mem_arena_allocator_init(MB(10));
+  Allocator allocator = wapp_mem_arena_allocator_init(KB(100));
   if (wapp_mem_allocator_invalid(&allocator)) {
     return wapp_tester_result(false);
   }
 
-  Str8 *s = wapp_str8_alloc_buf(&allocator, 4096);
-  result  = s != NULL && s->capacity == 4096;
+  u64 capacity = 4096;
 
+  Str8 *s = wapp_str8_alloc_buf(&allocator, capacity);
+  if (!s) {
+    result = false;
+    goto TEST_ALLOC_BUF_CLEANUP;
+  }
+
+  result  = s->capacity == capacity;
+
+  const char *cstr = "My name is Abdelrahman";
+  wapp_str8_copy_cstr_capped(s, cstr);
+
+  result = result && s->capacity == capacity && s->size == strlen(cstr) && memcmp(s->buf, cstr, s->size) == 0;
+
+TEST_ALLOC_BUF_CLEANUP:
   wapp_mem_arena_allocator_destroy(&allocator);
 
   return wapp_tester_result(result);
@@ -97,7 +110,7 @@ TestFuncResult test_str8_alloc_buf(void) {
 
 TestFuncResult test_str8_alloc_cstr(void) {
   bool result;
-  Allocator allocator = wapp_mem_arena_allocator_init(MB(10));
+  Allocator allocator = wapp_mem_arena_allocator_init(KB(100));
   if (wapp_mem_allocator_invalid(&allocator)) {
     return wapp_tester_result(false);
   }
@@ -118,7 +131,7 @@ TestFuncResult test_str8_alloc_cstr(void) {
 
 TestFuncResult test_str8_alloc_str8(void) {
   bool result;
-  Allocator allocator = wapp_mem_arena_allocator_init(MB(10));
+  Allocator allocator = wapp_mem_arena_allocator_init(KB(100));
   if (wapp_mem_allocator_invalid(&allocator)) {
     return wapp_tester_result(false);
   }
@@ -129,7 +142,27 @@ TestFuncResult test_str8_alloc_str8(void) {
     return wapp_tester_result(false);
   }
 
-  result = s->size == str.size && memcmp(s->buf, str.buf, str.size) == 0;
+  result = wapp_str8_equal(s, &str);
+
+  wapp_mem_arena_allocator_destroy(&allocator);
+
+  return wapp_tester_result(result);
+}
+
+TestFuncResult test_str8_alloc_substr(void) {
+  bool result;
+  Allocator allocator = wapp_mem_arena_allocator_init(KB(100));
+  if (wapp_mem_allocator_invalid(&allocator)) {
+    return wapp_tester_result(false);
+  }
+
+  Str8 str = wapp_str8_lit("Abdelrahman");
+  Str8 *s  = wapp_str8_alloc_substr(&allocator, &str, 3, 8);
+  if (!s) {
+    return wapp_tester_result(false);
+  }
+
+  result = s->size == 5 && memcmp(s->buf, "elrah", s->size) == 0;
 
   wapp_mem_arena_allocator_destroy(&allocator);
 
@@ -218,20 +251,20 @@ TestFuncResult test_str8_equal(void) {
   return wapp_tester_result(result);
 }
 
-TestFuncResult test_str8_substr(void) {
+TestFuncResult test_str8_slice(void) {
   bool result;
   Str8 s = wapp_str8_lit("Different strokes for different folks");
 
-  Str8RO sub1 = wapp_str8_substr(&s, 3, 9);
+  Str8RO sub1 = wapp_str8_slice(&s, 3, 9);
   result = sub1.size == 6 && sub1.capacity == 6;
 
-  Str8RO sub2 = wapp_str8_substr(&s, 18, 21);
+  Str8RO sub2 = wapp_str8_slice(&s, 18, 21);
   result = result && sub2.size == 3 && sub2.capacity == 3;
 
-  Str8RO sub3 = wapp_str8_substr(&s, 5, 1);
+  Str8RO sub3 = wapp_str8_slice(&s, 5, 1);
   result = result && sub3.size == 0 && sub3.capacity == 0;
 
-  Str8RO sub4 = wapp_str8_substr(&s, 70, 80);
+  Str8RO sub4 = wapp_str8_slice(&s, 70, 80);
   result = result && sub4.size == 0 && sub4.capacity == 0;
 
   return wapp_tester_result(result);
@@ -239,7 +272,7 @@ TestFuncResult test_str8_substr(void) {
 
 TestFuncResult test_str8_concat(void) {
   bool result;
-  Allocator arena = wapp_mem_arena_allocator_init(MB(10));
+  Allocator arena = wapp_mem_arena_allocator_init(KB(100));
 
   Str8 str     = wapp_str8_lit("Hello world");
   Str8 suffix1 = wapp_str8_lit(" from me.");
@@ -347,7 +380,7 @@ TestFuncResult test_str8_rfind(void) {
 
 TestFuncResult test_str8_split(void) {
   bool result;
-  Allocator arena = wapp_mem_arena_allocator_init(MB(10));
+  Allocator arena = wapp_mem_arena_allocator_init(KB(100));
 
   Str8 str        = wapp_str8_lit("hello world from me");
   Str8 delim1     = wapp_str8_lit(" ");
@@ -356,14 +389,14 @@ TestFuncResult test_str8_split(void) {
   Str8List *list2 = wapp_str8_split(&arena, &str, &delim2);
 
   Str8RO splits1[] = {
-    wapp_str8_substr(&str, 0, 5),
-    wapp_str8_substr(&str, 6, 11),
-    wapp_str8_substr(&str, 12, 16),
-    wapp_str8_substr(&str, 17, 19),
+    wapp_str8_slice(&str, 0, 5),
+    wapp_str8_slice(&str, 6, 11),
+    wapp_str8_slice(&str, 12, 16),
+    wapp_str8_slice(&str, 17, 19),
   };
   Str8RO splits2[] = {
-    wapp_str8_substr(&str, 0, 12),
-    wapp_str8_substr(&str, 16, 19),
+    wapp_str8_slice(&str, 0, 12),
+    wapp_str8_slice(&str, 16, 19),
   };
 
   u64 index1    = 0;
@@ -404,16 +437,16 @@ TestFuncResult test_str8_split(void) {
 
 TestFuncResult test_str8_split_with_max(void) {
   bool result;
-  Allocator arena = wapp_mem_arena_allocator_init(MB(10));
+  Allocator arena = wapp_mem_arena_allocator_init(KB(100));
 
   Str8 str       = wapp_str8_lit("hello world from me");
   Str8 delim     = wapp_str8_lit(" ");
   Str8List *list = wapp_str8_split_with_max(&arena, &str, &delim, 2);
 
   Str8RO splits[] = {
-    wapp_str8_substr(&str, 0, 5),
-    wapp_str8_substr(&str, 6, 11),
-    wapp_str8_substr(&str, 12, 19),
+    wapp_str8_slice(&str, 0, 5),
+    wapp_str8_slice(&str, 6, 11),
+    wapp_str8_slice(&str, 12, 19),
   };
 
   u64 index    = 0;
@@ -439,7 +472,7 @@ TestFuncResult test_str8_split_with_max(void) {
 
 TestFuncResult test_str8_rsplit(void) {
   bool result;
-  Allocator arena = wapp_mem_arena_allocator_init(MB(10));
+  Allocator arena = wapp_mem_arena_allocator_init(KB(100));
 
   Str8 str        = wapp_str8_lit("hello world from me");
   Str8 delim1     = wapp_str8_lit(" ");
@@ -448,14 +481,14 @@ TestFuncResult test_str8_rsplit(void) {
   Str8List *list2 = wapp_str8_rsplit(&arena, &str, &delim2);
 
   Str8RO splits1[] = {
-    wapp_str8_substr(&str, 0, 5),
-    wapp_str8_substr(&str, 6, 11),
-    wapp_str8_substr(&str, 12, 16),
-    wapp_str8_substr(&str, 17, 19),
+    wapp_str8_slice(&str, 0, 5),
+    wapp_str8_slice(&str, 6, 11),
+    wapp_str8_slice(&str, 12, 16),
+    wapp_str8_slice(&str, 17, 19),
   };
   Str8RO splits2[] = {
-    wapp_str8_substr(&str, 0, 12),
-    wapp_str8_substr(&str, 16, 19),
+    wapp_str8_slice(&str, 0, 12),
+    wapp_str8_slice(&str, 16, 19),
   };
 
   u64 index1    = 0;
@@ -496,16 +529,16 @@ TestFuncResult test_str8_rsplit(void) {
 
 TestFuncResult test_str8_rsplit_with_max(void) {
   bool result;
-  Allocator arena = wapp_mem_arena_allocator_init(MB(10));
+  Allocator arena = wapp_mem_arena_allocator_init(KB(100));
 
   Str8 str       = wapp_str8_lit("hello world from me");
   Str8 delim     = wapp_str8_lit(" ");
   Str8List *list = wapp_str8_rsplit_with_max(&arena, &str, &delim, 2);
 
   Str8RO splits[] = {
-    wapp_str8_substr(&str, 0, 11),
-    wapp_str8_substr(&str, 12, 16),
-    wapp_str8_substr(&str, 17, 19),
+    wapp_str8_slice(&str, 0, 11),
+    wapp_str8_slice(&str, 12, 16),
+    wapp_str8_slice(&str, 17, 19),
   };
 
   u64 index    = 0;
@@ -531,7 +564,7 @@ TestFuncResult test_str8_rsplit_with_max(void) {
 
 TestFuncResult test_str8_join(void) {
   bool result;
-  Allocator arena = wapp_mem_arena_allocator_init(MB(10));
+  Allocator arena = wapp_mem_arena_allocator_init(KB(100));
 
   Str8 str        = wapp_str8_lit("hello world from me");
   Str8 delim1     = wapp_str8_lit(" ");
diff --git a/tests/str8/test_str8.h b/tests/str8/test_str8.h
index 9febfcd..4a60836 100644
--- a/tests/str8/test_str8.h
+++ b/tests/str8/test_str8.h
@@ -13,11 +13,12 @@ TestFuncResult test_str8_buf(void);
 TestFuncResult test_str8_alloc_buf(void);
 TestFuncResult test_str8_alloc_cstr(void);
 TestFuncResult test_str8_alloc_str8(void);
+TestFuncResult test_str8_alloc_substr(void);
 TestFuncResult test_str8_get_index_within_bounds(void);
 TestFuncResult test_str8_get_index_out_of_bounds(void);
 TestFuncResult test_str8_set(void);
 TestFuncResult test_str8_equal(void);
-TestFuncResult test_str8_substr(void);
+TestFuncResult test_str8_slice(void);
 TestFuncResult test_str8_concat(void);
 TestFuncResult test_str8_concat_capped(void);
 TestFuncResult test_str8_copy_cstr_capped(void);
diff --git a/tests/wapptest.c b/tests/wapptest.c
index 1c5abd0..840d7cf 100644
--- a/tests/wapptest.c
+++ b/tests/wapptest.c
@@ -19,11 +19,12 @@ int main(void) {
                         test_str8_alloc_buf,
                         test_str8_alloc_cstr,
                         test_str8_alloc_str8,
+                        test_str8_alloc_substr,
                         test_str8_get_index_within_bounds,
                         test_str8_get_index_out_of_bounds,
                         test_str8_set,
                         test_str8_equal,
-                        test_str8_substr,
+                        test_str8_slice,
                         test_str8_concat,
                         test_str8_concat_capped,
                         test_str8_copy_cstr_capped,