summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2010-10-25 10:26:42 +0100
committerLars Wirzenius <liw@liw.fi>2010-10-25 10:26:42 +0100
commit14f4689353217eb64d95228143f0a9e37bc1c00f (patch)
treec4210d60a0031634c4af4c8942f7338893da2c0d
parentdc63cba068f760980e2249e2b932dc49cc1df41c (diff)
downloaddynstr-14f4689353217eb64d95228143f0a9e37bc1c00f.tar.gz
Implement dynstr_cmp.
-rw-r--r--dynstr.c22
-rw-r--r--dynstr.h5
-rw-r--r--unittests.c89
3 files changed, 116 insertions, 0 deletions
diff --git a/dynstr.c b/dynstr.c
index b3d4cbd..4805b45 100644
--- a/dynstr.c
+++ b/dynstr.c
@@ -267,6 +267,28 @@ size_t dynstr_last_string(Dynstr *dynstr, size_t offset, Dynstr *pattern)
}
+int dynstr_cmp(Dynstr *dynstr1, Dynstr *dynstr2)
+{
+ int result;
+ size_t min_size;
+
+ if (dynstr1->size < dynstr2->size)
+ min_size = dynstr1->size;
+ else
+ min_size = dynstr2->size;
+ result = memcmp(dynstr1->mem, dynstr2->mem, min_size);
+ if (result == 0) {
+ if (dynstr1->size < dynstr2->size)
+ return -1;
+ else if (dynstr1->size == dynstr2->size)
+ return 0;
+ else
+ return 1;
+ }
+ return result;
+}
+
+
size_t dynstr_fwrite(FILE *file, Dynstr *dynstr)
{
return fwrite(dynstr->mem, 1, dynstr->size, file);
diff --git a/dynstr.h b/dynstr.h
index b532074..d0ac247 100644
--- a/dynstr.h
+++ b/dynstr.h
@@ -131,6 +131,11 @@ size_t dynstr_last_byte(Dynstr *dynstr, size_t offset, int byte);
size_t dynstr_first_string(Dynstr *dynstr, size_t offset, Dynstr *pattern);
size_t dynstr_last_string(Dynstr *dynstr, size_t offset, Dynstr *pattern);
+/* Compare two strings, return 0 if they are equal, negative if the
+ * first comes before the second, and positive if second comes first.
+ * Comparisons are done byte-by-byte using unsigned values. */
+int dynstr_cmp(Dynstr *dynstr1, Dynstr *dynstr2);
+
/* Write a dynamic string into an open file, either FILE or a Unix file
* handle. Return value is number of bytes written, just like for fwrite(3).
* If an error occurs, the size is less than the length of the string,
diff --git a/unittests.c b/unittests.c
index 0a44542..95ce355 100644
--- a/unittests.c
+++ b/unittests.c
@@ -19,6 +19,16 @@
} while (0)
+#define FAIL_UNLESS(cond) \
+ do { \
+ if (!(cond)) { \
+ printf("FAIL: %s:%d: %s\n", \
+ __FUNCTION__, __LINE__, #cond); \
+ return false;\
+ } \
+ } while (0)
+
+
#define FAIL_UNLESS_EQUAL(a,b) \
do { \
if ((a) != (b)) { \
@@ -875,6 +885,79 @@ static int test_last_string_does_not_find_empty_pattern(void)
return true;
}
+static int test_cmp_returns_0_for_equal_strings(void)
+{
+ Dynstr *a;
+ Dynstr *b;
+
+ a = new_from_cstring("foo");
+ b = new_from_cstring("foo");
+ FAIL_UNLESS_EQUAL(dynstr_cmp(a, b), 0);
+ return true;
+}
+
+
+static int test_cmp_returns_0_for_empty_strings(void)
+{
+ Dynstr *a;
+ Dynstr *b;
+
+ a = dynstr_new_empty();
+ b = dynstr_new_empty();
+ FAIL_UNLESS_EQUAL(dynstr_cmp(a, b), 0);
+ dynstr_free(a);
+ dynstr_free(b);
+ return true;
+}
+
+
+static int test_cmp_returns_negative_if_only_first_string_is_empty(void)
+{
+ Dynstr *a;
+ Dynstr *b;
+
+ a = new_from_cstring("");
+ b = new_from_cstring("foo");
+ FAIL_UNLESS(dynstr_cmp(a, b) < 0);
+ return true;
+}
+
+
+static int test_cmp_returns_positive_if_only_second_string_is_empty(void)
+{
+ Dynstr *a;
+ Dynstr *b;
+
+ a = new_from_cstring("foo");
+ b = new_from_cstring("");
+ FAIL_UNLESS(dynstr_cmp(a, b) > 0);
+ return true;
+}
+
+
+static int test_cmp_returns_negative_if_first_string_comes_first(void)
+{
+ Dynstr *a;
+ Dynstr *b;
+
+ a = new_from_cstring("x");
+ b = new_from_cstring("\xff"); /* Check for unsigned comparision, too. */
+ FAIL_UNLESS(dynstr_cmp(a, b) < 0);
+ return true;
+}
+
+
+static int test_cmp_returns_positive_if_second_string_comes_first(void)
+{
+ Dynstr *a;
+ Dynstr *b;
+
+ a = new_from_cstring("\xff");
+ b = new_from_cstring("x");
+ FAIL_UNLESS(dynstr_cmp(a, b) > 0);
+ return true;
+}
+
static int test_fwrite_writes_string(void)
{
@@ -983,6 +1066,12 @@ static const struct test tests[] = {
TEST(test_last_string_does_not_find_pattern_outside_range),
TEST(test_last_string_only_finds_pattern_inside_range),
TEST(test_last_string_does_not_find_empty_pattern),
+ TEST(test_cmp_returns_0_for_equal_strings),
+ TEST(test_cmp_returns_0_for_empty_strings),
+ TEST(test_cmp_returns_negative_if_only_first_string_is_empty),
+ TEST(test_cmp_returns_positive_if_only_second_string_is_empty),
+ TEST(test_cmp_returns_negative_if_first_string_comes_first),
+ TEST(test_cmp_returns_positive_if_second_string_comes_first),
TEST(test_fwrite_writes_string),
};
static const int num_tests = sizeof(tests) / sizeof(tests[0]);