From 14f4689353217eb64d95228143f0a9e37bc1c00f Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Mon, 25 Oct 2010 10:26:42 +0100 Subject: Implement dynstr_cmp. --- dynstr.c | 22 +++++++++++++++ dynstr.h | 5 ++++ unittests.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) 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]); -- cgit v1.2.1