added sstrstr() function + improved sstrsplit variants by using sstrprefix()

Tue, 27 Oct 2015 15:29:34 +0100

author
Mike Becker <universe@uap-core.de>
date
Tue, 27 Oct 2015 15:29:34 +0100
changeset 214
2bc19726c340
parent 213
fa8b745be7b5
child 215
e0853e077770

added sstrstr() function + improved sstrsplit variants by using sstrprefix()

test/main.c file | annotate | diff | comparison | revisions
test/string_tests.c file | annotate | diff | comparison | revisions
test/string_tests.h file | annotate | diff | comparison | revisions
ucx/string.c file | annotate | diff | comparison | revisions
ucx/string.h file | annotate | diff | comparison | revisions
--- a/test/main.c	Mon Oct 26 14:09:45 2015 +0100
+++ b/test/main.c	Tue Oct 27 15:29:34 2015 +0100
@@ -125,6 +125,7 @@
         ucx_test_register(suite, test_sstrcasecmp);
         ucx_test_register(suite, test_sstrcat);
         ucx_test_register(suite, test_sstrchr_sstrrchr);
+        ucx_test_register(suite, test_sstrstr);
         ucx_test_register(suite, test_sstrsplit);
         ucx_test_register(suite, test_sstrtrim);
         ucx_test_register(suite, test_sstrprefixsuffix);
--- a/test/string_tests.c	Mon Oct 26 14:09:45 2015 +0100
+++ b/test/string_tests.c	Tue Oct 27 15:29:34 2015 +0100
@@ -79,6 +79,27 @@
     UCX_TEST_END
 }
 
+UCX_TEST(test_sstrstr) {
+    sstr_t str = ST("find the match in this string");
+    UCX_TEST_BEGIN
+    
+    sstr_t notfound = sstrstr(str, S("no match"));
+    UCX_TEST_ASSERT(notfound.length == 0, "no match must return empty string");
+    
+    sstr_t result = sstrstr(str, S("match"));
+    UCX_TEST_ASSERT(result.length == 20, "sstrstr returned wrong length");
+    UCX_TEST_ASSERT(!strcmp("match in this string", result.ptr),
+        "sstrstr did not return the expected string");
+    
+    result = sstrstr(str, S(""));
+    UCX_TEST_ASSERT(result.length == str.length,
+        "sstrstr with empty match string returned wrong length");
+    UCX_TEST_ASSERT(!strcmp(str.ptr, result.ptr),
+        "sstrstr with empty match string did not return the original string");
+    
+    UCX_TEST_END
+}
+
 UCX_TEST(test_sstrcmp) {
     sstr_t str = ST("compare this");
     
--- a/test/string_tests.h	Mon Oct 26 14:09:45 2015 +0100
+++ b/test/string_tests.h	Tue Oct 27 15:29:34 2015 +0100
@@ -42,6 +42,7 @@
 UCX_TEST(test_sstrcasecmp);
 UCX_TEST(test_sstrcat);
 UCX_TEST(test_sstrchr_sstrrchr);
+UCX_TEST(test_sstrstr);
 UCX_TEST(test_sstrsplit);
 UCX_TEST(test_sstrtrim);
 UCX_TEST(test_sstrprefixsuffix);
--- a/ucx/string.c	Mon Oct 26 14:09:45 2015 +0100
+++ b/ucx/string.c	Tue Oct 27 15:29:34 2015 +0100
@@ -175,6 +175,24 @@
     return n;
 }
 
+sstr_t sstrstr(sstr_t string, sstr_t match) {
+    if (match.length == 0) {
+        return string;
+    }
+    
+    for (size_t i = 0 ; i < string.length ; i++) {
+        sstr_t substr = sstrsubs(string, i);
+        if (sstrprefix(substr, match)) {
+            return substr;
+        }
+    }
+    
+    sstr_t emptystr;
+    emptystr.length = 0;
+    emptystr.ptr = NULL;
+    return emptystr;
+}
+
 sstr_t* sstrsplit(sstr_t s, sstr_t d, ssize_t *n) {
     return sstrsplit_a(ucx_default_allocator(), s, d, n);
 }
@@ -201,23 +219,13 @@
     }
 
     for (size_t i = 0 ; i < s.length ; i++) {
-        if (sv.ptr[i] == d.ptr[0]) {
-            _Bool match = 1;
-            for (size_t j = 1 ; j < d.length ; j++) {
-                if (j+i < s.length) {
-                    match &= (sv.ptr[i+j] == d.ptr[j]);
-                } else {
-                    match = 0;
-                    break;
-                }
+        sstr_t substr = sstrsubs(sv, i);
+        if (sstrprefix(substr, d)) {
+            (*n)++;
+            for (size_t j = 0 ; j < d.length ; j++) {
+                sv.ptr[i+j] = 0;
             }
-            if (match) {
-                (*n)++;
-                for (size_t j = 0 ; j < d.length ; j++) {
-                    sv.ptr[i+j] = 0;
-                }
-                i += d.length - 1; // -1, because the loop will do a i++
-            }
+            i += d.length - 1; // -1, because the loop will do a i++
         }
         if ((*n) == nmax) break;
     }
--- a/ucx/string.h	Mon Oct 26 14:09:45 2015 +0100
+++ b/ucx/string.h	Tue Oct 27 15:29:34 2015 +0100
@@ -214,6 +214,23 @@
 sstr_t sstrrchr(sstr_t string, int chr);
 
 /**
+ * Returns a substring starting at the location of the first occurrence of the
+ * specified string.
+ * 
+ * If the string does not contain the other string, an empty string is returned.
+ * 
+ * If <code>match</code> is an empty string, the complete <code>string</code> is
+ * returned.
+ * 
+ * @param string the string to be scanned
+ * @param match  string containing the sequence of characters to match
+ * @return       a substring starting at the first occurrence of
+ *               <code>match</code>, or an empty string, if the sequence is not
+ *               present in <code>string</code>
+ */
+sstr_t sstrstr(sstr_t string, sstr_t match);
+
+/**
  * Splits a string into parts by using a delimiter string.
  * 
  * This function will return <code>NULL</code>, if one of the following happens:

mercurial