Quellcode durchsuchen

find_first, find_last, and truncate functions for SCDString.

Aaro Saila vor 1 Woche
Ursprung
Commit
5166113360
3 geänderte Dateien mit 188 neuen und 0 gelöschten Zeilen
  1. 76 0
      include/scufcont/DString.h
  2. 58 0
      src/DString.c
  3. 54 0
      tests/cmocka/DString_tests.c

+ 76 - 0
include/scufcont/DString.h

@@ -92,6 +92,79 @@ ScufContResult SCDString_alloc_concat_c_strs(
 );
 
 /**
+  @brief Seek substr in dstr from the left/beginning
+         of the string.
+
+  @param[out] at
+      The index of the first char of substr in dstr.
+
+  @return true substr was found in dstr.
+  @return false substr was not found in dstr.
+*/
+bool SCDString_find_first_c_str(
+    const SCDString *const dstr,
+    const char *substr,
+    const size_t substr_len,
+    size_t *const at
+);
+
+/**
+  @brief Seek substr in dstr from the left/beginning
+         of the string.
+
+  @param[out] at
+      The index of the first char of substr in dstr.
+
+  @return true substr was found in dstr.
+  @return false substr was not found in dstr.
+*/
+bool SCDString_find_first(
+    const SCDString *const dstr,
+    const SCDString *const substr,
+    size_t *const at
+);
+
+/**
+  @brief Seek substr in dstr from the right/end
+         of the string.
+
+  @param[out] at
+      The index of the first char of substr in dstr.
+
+  @return true substr was found in dstr.
+  @return false substr was not found in dstr.
+*/
+bool SCDString_find_last_c_str(
+    const SCDString *const dstr,
+    const char *substr,
+    const size_t substr_len,
+    size_t *const at
+);
+
+/**
+  @brief Seek substr in dstr from the right/end
+         of the string.
+
+  @param[out] at
+      The index of the first char of substr in dstr.
+
+  @return true substr was found in dstr.
+  @return false substr was not found in dstr.
+*/
+bool SCDString_find_last(
+    const SCDString *const dstr,
+    const SCDString *substr,
+    size_t *const at
+);
+
+/**
+  @param[out] split_arr
+      Pointer to an array of SCDStrings containing the split elements.
+      Free with SCDString_split_arr_free.
+
+  @param[out] arr_len
+      The length of split_arr.
+
   @return SCUFCONT_OUT_OF_MEMORY
   @return SCUFCONT_SUCCESS
 */
@@ -129,6 +202,9 @@ ScufContResult SCDString_char_remove(SCDString *const dstr, const size_t at);
 */
 ScufContResult SCDString_char_insert(SCDString *const dstr, const size_t at, const char ch);
 
+void SCDString_truncate_no_shrink(SCDString *const dstr, const size_t at);
+void SCDString_truncate(SCDString *const dstr, const size_t at);
+
 /**
   @return SCUFCONT_OUT_OF_MEMORY
   @return SCUFCONT_SUCCESS

+ 58 - 0
src/DString.c

@@ -185,6 +185,54 @@ ScufContResult SCDString_alloc_concat_c_strs(
     return SCUFCONT_SUCCESS;
 }
 
+bool SCDString_find_first_c_str(
+    const SCDString *const dstr,
+    const char *substr,
+    const size_t substr_len,
+    size_t *const at
+) {
+    for (size_t i = 0; i < dstr->len; i++) {
+        if (strncmp(dstr->data + i, substr, substr_len) == 0) {
+            *at = i;
+            return true;
+        }
+    }
+
+    return false;
+}
+
+bool SCDString_find_first(
+    const SCDString *const dstr,
+    const SCDString *const substr,
+    size_t *const at
+) {
+    return SCDString_find_first_c_str(dstr, SCDString_c_str(substr), substr->len, at);
+}
+
+bool SCDString_find_last_c_str(
+    const SCDString *const dstr,
+    const char *substr,
+    const size_t substr_len,
+    size_t *const at
+) {
+    for (size_t i = dstr->len - substr_len; i >= 0; i--) {
+        if (strncmp(dstr->data + i, substr, substr_len) == 0) {
+            *at = i;
+            return true;
+        }
+    }
+
+    return false;
+}
+
+bool SCDString_find_last(
+    const SCDString *const dstr,
+    const SCDString *substr,
+    size_t *const at
+) {
+    return SCDString_find_last_c_str(dstr, SCDString_c_str(substr), substr->len, at);
+}
+
 ScufContResult SCDString_split(
     const SCDString *const dstr,
     const char *delim,
@@ -297,6 +345,16 @@ ScufContResult SCDString_char_insert(SCDString *const dstr, const size_t at, con
     return SCUFCONT_SUCCESS;
 }
 
+void SCDString_truncate_no_shrink(SCDString *const dstr, const size_t at) {
+    dstr->data[at] = '\0';
+    dstr->len = strlen(dstr->data);
+}
+
+void SCDString_truncate(SCDString *const dstr, const size_t at) {
+    SCDString_truncate_no_shrink(dstr, at);
+    SCDString_shrink_to_fit(dstr);
+}
+
 ScufContResult SCDString_replace_c_str_no_shrink(SCDString *const dstr, const char *str, const size_t str_len) {
     if (dstr->capacity < str_len + 1) {
         const ScufContResult res = SCDString_reserve(dstr, str_len + 1);

+ 54 - 0
tests/cmocka/DString_tests.c

@@ -161,6 +161,44 @@ void test_SCDString_concat_c_str(void **state) {
     SCDString_free(&dstr);
 }
 
+void test_SCDString_find_first_c_str(void **state) {
+    (void) state;
+
+    SCDString dstr;
+    char *substr;
+    size_t at;
+
+    assert_true(SCDString_alloc(&dstr, "Hello World", strlen("Hello World")) == SCUFCONT_SUCCESS);
+    substr = "o";
+    assert_true(SCDString_find_first_c_str(&dstr, substr, 1, &at));
+    assert_uint_equal(at, 4);
+
+    substr = "lo Worl";
+    assert_true(SCDString_find_first_c_str(&dstr, substr, strlen(substr), &at));
+    assert_uint_equal(at, 3);
+
+    SCDString_free(&dstr);
+}
+
+void test_SCDString_find_last_c_str(void **state) {
+    (void) state;
+
+    SCDString dstr;
+    char *substr;
+    size_t at;
+
+    assert_true(SCDString_alloc(&dstr, "Hello World", strlen("Hello World")) == SCUFCONT_SUCCESS);
+    substr = "o";
+    assert_true(SCDString_find_last_c_str(&dstr, substr, 1, &at));
+    assert_uint_equal(at, 7);
+
+    substr = "lo Worl";
+    assert_true(SCDString_find_last_c_str(&dstr, substr, strlen(substr), &at));
+    assert_uint_equal(at, 3);
+
+    SCDString_free(&dstr);
+}
+
 void test_SCDString_c_str(void **state) {
     (void) state;
 
@@ -287,6 +325,19 @@ void test_SCDString_char_insert(void **state) {
     SCDString_free(&dstr);
 }
 
+void test_SCDString_truncate(void **state) {
+    (void) state;
+
+    SCDString dstr;
+    assert_true(SCDString_alloc(&dstr, "Hello World", strlen("Hello World")) == SCUFCONT_SUCCESS);
+
+    SCDString_truncate(&dstr, 5);
+    assert_string_equal(SCDString_c_str(&dstr), "Hello");
+
+    SCDString_truncate(&dstr, 0);
+    assert_string_equal(SCDString_c_str(&dstr), "");
+}
+
 void test_SCDString_replace_c_str(void **state) {
     (void) state;
 
@@ -329,11 +380,14 @@ int DString_tests_run(void) {
         cmocka_unit_test(test_SCDString_equal_next_chars_c_str),
         cmocka_unit_test(test_SCDString_concat_char),
         cmocka_unit_test(test_SCDString_concat_c_str),
+        cmocka_unit_test(test_SCDString_find_first_c_str),
+        cmocka_unit_test(test_SCDString_find_last_c_str),
         cmocka_unit_test(test_SCDString_c_str),
         cmocka_unit_test(test_SCDString_split),
         cmocka_unit_test(test_SCDString_char_mod),
         cmocka_unit_test(test_SCDString_char_remove),
         cmocka_unit_test(test_SCDString_char_insert),
+        cmocka_unit_test(test_SCDString_truncate),
         cmocka_unit_test(test_SCDString_replace_c_str),
         cmocka_unit_test(test_SCDString_trim_whitespace),
     };