Add a string comparison function and a string equality predicate.

Write test cases for the former.
This commit is contained in:
Dag-Erling Smørgrav 2014-12-29 12:41:39 +00:00 committed by des
parent 1a76a0cbb0
commit 2ad45cfccf
7 changed files with 156 additions and 43 deletions

View file

@ -41,6 +41,8 @@
#define string_append_string cryb_string_append_string
#define string_printf cryb_string_printf
#define string_vprintf cryb_string_vprintf
#define string_compare cryb_string_compare
#define string_equal cryb_string_equal
typedef struct cryb_string string;
@ -57,5 +59,7 @@ ssize_t string_printf(string *, const char *, ...);
#ifdef va_start
ssize_t string_vprintf(string *, const char *, va_list);
#endif
int string_compare(const string *, const string *);
int string_equal(const string *, const string *);
#endif

View file

@ -41,6 +41,8 @@
#define wstring_append_wstring cryb_wstring_append_wstring
#define wstring_printf cryb_wstring_printf
#define wstring_vprintf cryb_wstring_vprintf
#define wstring_compare cryb_wstring_compare
#define wstring_equal cryb_wstring_equal
typedef struct cryb_wstring wstring;
@ -50,12 +52,14 @@ void wstring_delete(wstring *);
int wstring_expand(wstring *, size_t);
void wstring_shrink(wstring *);
ssize_t wstring_trunc(wstring *, size_t);
ssize_t wstring_append_c(wstring *, wchar_t);
ssize_t wstring_append_cs(wstring *, const wchar_t *, size_t);
ssize_t wstring_append_wc(wstring *, wchar_t);
ssize_t wstring_append_wcs(wstring *, const wchar_t *, size_t);
ssize_t wstring_append_wstring(wstring *, const wstring *, size_t);
ssize_t wstring_printf(wstring *, const wchar_t *, ...);
#ifdef va_start
ssize_t wstring_vprintf(wstring *, const wchar_t *, va_list);
#endif
int wstring_compare(const wstring *, const wstring *);
int wstring_equal(const wstring *, const wstring *);
#endif

View file

@ -280,3 +280,34 @@ string_vprintf(string *str, const char_t *fmt, va_list ap)
str->buf[str->len] = 0;
return (str->len);
}
/*
* Compare two strings, returning a negative value if the first is
* lexically less than the second, a positive value if the opposite is
* true, and zero if they are equal.
*/
int
string_compare(const string *s1, const string *s2)
{
const char_t *p1, *p2;
for (p1 = s1->buf, p2 = s2->buf; *p1 && *p2; ++p1, ++p2)
if (*p1 != *p2)
return (*p1 < *p2 ? -1 : 1);
return (*p1 ? 1 : *p2 ? -1 : 0);
}
/*
* Compare two strings, returning true (non-zero) if they are equal and
* false (zero) if they are not.
*/
int
string_equal(const string *s1, const string *s2)
{
const char_t *p1, *p2;
for (p1 = s1->buf, p2 = s2->buf; *p1 && *p2; ++p1, ++p2)
if (*p1 != *p2)
return (0);
return (1);
}

View file

@ -54,5 +54,7 @@
#define string_append_string wstring_append_wstring
#define string_printf wstring_printf
#define string_vprintf wstring_vprintf
#define string_compare wstring_compare
#define string_equal wstring_equal
#include "_string.c"

View file

@ -28,7 +28,7 @@
*/
static int
t_foo(char **desc CRYB_UNUSED, void *arg)
t_noop(char **desc CRYB_UNUSED, void *arg)
{
string *str;
@ -38,3 +38,106 @@ t_foo(char **desc CRYB_UNUSED, void *arg)
string_delete(str);
return (1);
}
/***************************************************************************
* Comparisons
*/
static struct t_compare_case {
const char *desc;
const char_t *s1, *s2;
int cmp;
} t_compare_cases[] = {
{
"both empty",
CS(""),
CS(""),
0,
},
{
"empty with non-empty (left)",
CS(""),
CS("xyzzy"),
-1,
},
{
"empty with non-empty (right)",
CS("xyzzy"),
CS(""),
1,
},
{
"equal non-empty",
CS("xyzzy"),
CS("xyzzy"),
0,
},
{
"unequal of equal length (left)",
CS("abba"),
CS("baba"),
-1,
},
{
"unequal of equal length (right)",
CS("baba"),
CS("abba"),
1,
},
{
"prefix (left)",
CS("baba"),
CS("babaorum"),
-1,
},
{
"prefix (right)",
CS("babaorum"),
CS("baba"),
1,
},
};
static int
t_compare_test(char **desc CRYB_UNUSED, void *arg)
{
struct t_compare_case *t = arg;
string *s1, *s2;
int ret;
if ((s1 = string_new()) == NULL ||
string_append_cs(s1, t->s1, SIZE_MAX) < 0 ||
(s2 = string_new()) == NULL ||
string_append_cs(s2, t->s2, SIZE_MAX) < 0)
return (0);
ret = string_compare(s1, s2) == t->cmp;
string_delete(s2);
string_delete(s1);
return (ret);
}
/***************************************************************************
* Boilerplate
*/
int
t_prepare(int argc, char *argv[])
{
unsigned int i;
(void)argc;
(void)argv;
t_add_test(t_noop, NULL, "no-op");
for (i = 0; i < sizeof t_compare_cases / sizeof *t_compare_cases; ++i)
t_add_test(t_compare_test, &t_compare_cases[i],
t_compare_cases[i].desc);
return (0);
}
void
t_cleanup(void)
{
}

View file

@ -38,24 +38,8 @@
#include "t.h"
#define char_t char
#define CS(lit) lit
#include "t__string.c"
/***************************************************************************
* Boilerplate
*/
int
t_prepare(int argc, char *argv[])
{
(void)argc;
(void)argv;
t_add_test(t_foo, NULL, "foo");
return (0);
}
void
t_cleanup(void)
{
}

View file

@ -40,6 +40,7 @@
#include "t.h"
#define char_t wchar_t
#define vsnprintf vswprintf
#define cryb_string cryb_wstring
#define string wstring
@ -55,25 +56,9 @@
#define string_append_string wstring_append_wstring
#define string_printf wstring_printf
#define string_vprintf wstring_vprintf
#define string_compare wstring_compare
#define string_equal wstring_equal
#define CS(lit) L ## lit
#include "t__string.c"
/***************************************************************************
* Boilerplate
*/
int
t_prepare(int argc, char *argv[])
{
(void)argc;
(void)argv;
t_add_test(t_foo, NULL, "foo");
return (0);
}
void
t_cleanup(void)
{
}