From 8757a26cbbabd54c5662bf9b492214fe937dc93a Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Mon, 9 Jan 2006 17:20:59 +0000 Subject: Fixed bugs and added tests to handle NULL and zero length strings git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@118 74dad513-b988-da41-8d7b-12977e46ad98 --- pjlib/include/pj/string_i.h | 68 +++++++++++++++++++++++++++++++----------- pjlib/src/pjlib-test/main.c | 13 +++++++- pjlib/src/pjlib-test/string.c | 69 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 128 insertions(+), 22 deletions(-) diff --git a/pjlib/include/pj/string_i.h b/pjlib/include/pj/string_i.h index 91aebfb0..937b0840 100644 --- a/pjlib/include/pj/string_i.h +++ b/pjlib/include/pj/string_i.h @@ -129,7 +129,7 @@ PJ_IDEF(int) pj_strcmp( const pj_str_t *str1, const pj_str_t *str2) diff = str1->slen - str2->slen; if (diff) { - return (int)diff; + return diff > 0 ? 1 : -1; } else if (str1->ptr && str1->slen) { return pj_native_strncmp(str1->ptr, str2->ptr, str1->slen); } else { @@ -140,21 +140,37 @@ PJ_IDEF(int) pj_strcmp( const pj_str_t *str1, const pj_str_t *str2) PJ_IDEF(int) pj_strncmp( const pj_str_t *str1, const pj_str_t *str2, pj_size_t len) { - return (str1->ptr && str2->ptr) ? - pj_native_strncmp(str1->ptr, str2->ptr, len) : - (str1->ptr == str2->ptr ? 0 : 1); + if (str1->ptr && str2->ptr) + return pj_native_strncmp(str1->ptr, str2->ptr, len); + else if (str2->ptr) + return str2->slen==0 ? 0 : -1; + else if (str1->ptr) + return str1->slen==0 ? 0 : 1; + else + return 0; } PJ_IDEF(int) pj_strncmp2( const pj_str_t *str1, const char *str2, pj_size_t len) { - return (str1->ptr && str2) ? pj_native_strncmp(str1->ptr, str2, len) : - (str1->ptr==str2 ? 0 : 1); + if (len == 0) + return 0; + else if (str1->ptr && str2) + return pj_native_strncmp(str1->ptr, str2, len); + else if (str1->ptr) + return str1->slen==0 ? 0 : 1; + else if (str2) + return *str2=='\0' ? 0 : -1; + else + return 0; } PJ_IDEF(int) pj_strcmp2( const pj_str_t *str1, const char *str2 ) { - return pj_strncmp2( str1, str2, str1->slen); + if (str1->slen == 0) { + return (!str2 || *str2=='\0') ? 0 : -1; + } else + return pj_strncmp2( str1, str2, str1->slen); } PJ_IDEF(int) pj_stricmp( const pj_str_t *str1, const pj_str_t *str2) @@ -207,7 +223,7 @@ PJ_IDEF(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2) register int len = str1->slen; if (len != str2->slen) { - return -1; + return (len < str2->slen) ? -1 : 1; } else if (len == 0) { return 0; } else { @@ -240,25 +256,43 @@ PJ_IDEF(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2) PJ_IDEF(int) pj_stricmp2( const pj_str_t *str1, const char *str2) { - return (str1->ptr && str2) ? - pj_native_strnicmp(str1->ptr, str2, str1->slen) : - (str1->ptr==str2 ? 0 : 1); + if (str1->ptr && str2) + return pj_native_strnicmp(str1->ptr, str2, str1->slen); + else if (str2) + return (*str2=='\0') ? 0 : -1; + else if (str1->ptr) + return (str1->slen==0) ? 0 : 1; + else + return 0; } PJ_IDEF(int) pj_strnicmp( const pj_str_t *str1, const pj_str_t *str2, pj_size_t len) { - return (str1->ptr && str2->ptr) ? - pj_native_strnicmp(str1->ptr, str2->ptr, len) : - (str1->ptr == str2->ptr ? 0 : 1); + if (str1->ptr && str2->ptr) + return pj_native_strnicmp(str1->ptr, str2->ptr, len); + else if (str2->ptr) + return str2->slen==0 ? 0 : -1; + else if (str1->ptr) + return str1->slen==0 ? 0 : 1; + else + return 0; } PJ_IDEF(int) pj_strnicmp2( const pj_str_t *str1, const char *str2, pj_size_t len) { - return (str1->ptr && str2) ? - pj_native_strnicmp(str1->ptr, str2, len) : - (str1->ptr == str2 ? 0 : 1); + if (len == 0) + return 0; + else if (str1->ptr && str2) + return pj_native_strnicmp(str1->ptr, str2, len); + else if (str1->ptr) + return str1->slen==0 ? 0 : 1; + else if (str2) + return *str2=='\0' ? 0 : -1; + else + return 0; + } PJ_IDEF(void) pj_strcat(pj_str_t *dst, const pj_str_t *src) diff --git a/pjlib/src/pjlib-test/main.c b/pjlib/src/pjlib-test/main.c index fea4cd6f..20a34478 100644 --- a/pjlib/src/pjlib-test/main.c +++ b/pjlib/src/pjlib-test/main.c @@ -57,6 +57,7 @@ static void init_signals() int main(int argc, char *argv[]) { int rc; + int interractive = 0; boost(); init_signals(); @@ -64,7 +65,10 @@ int main(int argc, char *argv[]) while (argc > 1) { char *arg = argv[--argc]; - if (*arg=='-' && *(arg+1)=='p') { + if (*arg=='-' && *(arg+1)=='i') { + interractive = 1; + + } else if (*arg=='-' && *(arg+1)=='p') { pj_str_t port = pj_str(argv[--argc]); param_echo_port = pj_strtoul(&port); @@ -88,6 +92,13 @@ int main(int argc, char *argv[]) rc = test_main(); + if (interractive) { + char s[10]; + puts(""); + puts("Press to exit"); + fgets(s, sizeof(s), stdin); + } + return rc; } diff --git a/pjlib/src/pjlib-test/string.c b/pjlib/src/pjlib-test/string.c index ba7c9144..8ca2de0d 100644 --- a/pjlib/src/pjlib-test/string.c +++ b/pjlib/src/pjlib-test/string.c @@ -47,7 +47,7 @@ * - pj_utoa() * - pj_strtoul() * - pj_create_random_string() - * + * - ... and mode.. * * This file is pjlib-test/string.c * @@ -66,10 +66,14 @@ static int stricmp_test(void) { +/* This specificly tests and benchmark pj_stricmp(), pj_stricmp_alnum(). + * In addition, it also tests pj_stricmp2(), pj_strnicmp(), and + * pj_strnicmp2(). + */ #define STRTEST(res,S1,S2,code) \ do { \ - s1.ptr=S1; s1.slen=len; \ - s2.ptr=S2; s2.slen=len; \ + s1.ptr=S1; s1.slen=S1?len:0; \ + s2.ptr=S2; s2.slen=S2?len:0; \ pj_get_timestamp(&t1); \ if (pj_stricmp(&s1,&s2)!=res) return code; \ pj_get_timestamp(&t2); \ @@ -80,6 +84,9 @@ static int stricmp_test(void) pj_get_timestamp(&t2); \ pj_sub_timestamp(&t2, &t1); \ pj_add_timestamp(&e2, &t2); \ + if (pj_stricmp2(&s1,S2)!=res) return code*10; \ + if (pj_strnicmp(&s1,&s2,len)!=res) return code*100; \ + if (pj_strnicmp2(&s1,S2,len)!=res) return code*1000; \ } while (0) char *buf; @@ -95,6 +102,10 @@ static int stricmp_test(void) /* Compare empty strings. */ len=0; STRTEST( 0, "","",-500); + STRTEST( 0, NULL,"",-502); + STRTEST( 0, "",NULL,-504); + STRTEST( 0, NULL,NULL,-506); + STRTEST( 0, "hello","world",-508); /* equal, length=1 * use buffer to simulate non-aligned string. @@ -104,6 +115,8 @@ static int stricmp_test(void) STRTEST( 0, "a",buf+0,-510); STRTEST( 0, "a",buf+1,-512); STRTEST( -1, "0", "P", -514); + STRTEST(-1, NULL, "a", -516); + STRTEST(1, "a", NULL, -518); /* equal, length=2 * use buffer to simulate non-aligned string. @@ -207,6 +220,44 @@ static int stricmp_test(void) #undef STRTEST } +/* This tests pj_strcmp(), pj_strcmp2(), pj_strncmp(), pj_strncmp2() */ +static int strcmp_test(void) +{ +#define STR_TEST(res,S1,S2,code) \ + do { \ + s1.ptr=S1; s1.slen=S1?len:0; \ + s2.ptr=S2; s2.slen=S2?len:0; \ + if (pj_strcmp(&s1,&s2)!=res) return code; \ + if (pj_strcmp2(&s1,S2)!=res) return code-1; \ + if (pj_strncmp(&s1,&s2,len)!=res) return code-2; \ + if (pj_strncmp2(&s1,S2,len)!=res) return code-3; \ + } while (0) + + pj_str_t s1, s2; + int len; + + /* Test with length == 0 */ + len=0; + STR_TEST(0, "", "", -400); + STR_TEST(0, NULL, "", -405); + STR_TEST(0, "", NULL, -410); + STR_TEST(0, NULL, NULL, -415); + STR_TEST(0, "hello", "", -420); + STR_TEST(0, "hello", NULL, -425); + + /* Test with length != 0 */ + len = 2; + STR_TEST(0, "12", "12", -430); + STR_TEST(1, "12", "1", -435); + STR_TEST(-1, "1", "12", -440); + STR_TEST(-1, NULL, "12", -445); + STR_TEST(1, "12", NULL, -450); + + return 0; + +#undef STR_TEST +} + int string_test(void) { const pj_str_t hello_world = { HELLO_WORLD, strlen(HELLO_WORLD) }; @@ -307,7 +358,17 @@ int string_test(void) /* Done. */ pj_pool_release(pool); - return stricmp_test(); + /* Case sensitive comparison test. */ + i = strcmp_test(); + if (i != 0) + return i; + + /* Caseless comparison test. */ + i = stricmp_test(); + if (i != 0) + return i; + + return 0; } #else -- cgit v1.2.3