From 2538cea71a2cbb6da297ec00f2949093a91a9edb Mon Sep 17 00:00:00 2001 From: Daniel Lehman Date: Fri, 30 Dec 2011 09:45:10 -0800 Subject: msvcp90: start rfind from given position substracting 1 unconditionally was returning the position before the real match. given pos should only be changed if beyond the bounds of the string --- dlls/msvcp90/string.c | 4 +- dlls/msvcp90/tests/string.c | 46 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/dlls/msvcp90/string.c b/dlls/msvcp90/string.c index 2ecd004..8a6bf64 100644 --- a/dlls/msvcp90/string.c +++ b/dlls/msvcp90/string.c @@ -1624,7 +1624,7 @@ MSVCP_size_t __thiscall MSVCP_basic_string_char_rfind_cstr_substr( if(pos > this->size-len+1) pos = this->size-len+1; end = basic_string_char_const_ptr(this); - for(p=end+pos-1; p>=end; p--) { + for(p=end+pos; p>=end; p--) { if(*p==*find && !MSVCP_char_traits_char_compare(p, find, len)) return p-basic_string_char_const_ptr(this); } @@ -3611,7 +3611,7 @@ MSVCP_size_t __thiscall MSVCP_basic_string_wchar_rfind_cstr_substr( if(pos > this->size-len+1) pos = this->size-len+1; end = basic_string_wchar_const_ptr(this); - for(p=end+pos-1; p>=end; p--) { + for(p=end+pos; p>=end; p--) { if(*p==*find && !MSVCP_char_traits_wchar_compare(p, find, len)) return p-basic_string_wchar_const_ptr(this); } diff --git a/dlls/msvcp90/tests/string.c b/dlls/msvcp90/tests/string.c index 60fa460..6857dee 100644 --- a/dlls/msvcp90/tests/string.c +++ b/dlls/msvcp90/tests/string.c @@ -74,6 +74,9 @@ static basic_string_char* (__thiscall *p_basic_string_char_append_substr)(basic_ static int (__thiscall *p_basic_string_char_compare_substr_substr)(basic_string_char*, size_t, size_t, basic_string_char*, size_t, size_t); static int (__thiscall *p_basic_string_char_compare_substr_cstr_len)(basic_string_char*, size_t, size_t, const char*, size_t); static size_t (__thiscall *p_basic_string_char_find_cstr_substr)(basic_string_char*, const char*, size_t, size_t); +static size_t (__thiscall *p_basic_string_char_rfind_cstr_substr)(basic_string_char*, const char*, size_t, size_t); + +static size_t *p_basic_string_char_npos; static basic_string_wchar* (__thiscall *p_basic_string_wchar_ctor)(basic_string_wchar*); static basic_string_wchar* (__thiscall *p_basic_string_wchar_copy_ctor)(basic_string_wchar*, basic_string_wchar*); @@ -219,6 +222,10 @@ static BOOL init(void) "??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@AEBV10@PEBD@Z"); SET(p_basic_string_char_find_cstr_substr, "?find@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KPEBD_K1@Z"); + SET(p_basic_string_char_rfind_cstr_substr, + "?rfind@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEBA_KPEBD_K1@Z"); + SET(p_basic_string_char_npos, + "?npos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@2_KB"); SET(p_basic_string_wchar_ctor, "??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@XZ"); @@ -279,6 +286,10 @@ static BOOL init(void) "??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@ABV10@PBD@Z"); SET(p_basic_string_char_find_cstr_substr, "?find@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIPBDII@Z"); + SET(p_basic_string_char_rfind_cstr_substr, + "?rfind@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIPBDII@Z"); + SET(p_basic_string_char_npos, + "?npos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@2IB"); SET(p_basic_string_wchar_ctor, "??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE@XZ"); @@ -503,6 +514,40 @@ static void test_basic_string_char_find(void) { call_func1(p_basic_string_char_dtor, &str); } +static void test_basic_string_char_rfind(void) { + struct rfind_char_test { + const char *str; + const char *find; + size_t pos; + size_t len; + size_t ret; + }; + + int i; + basic_string_char str; + size_t ret; + struct rfind_char_test tests[] = { + { "", "a", 0, 1, *p_basic_string_char_npos }, /* empty string */ + { "a", "", 0, 0, 0 }, /* empty find */ + { "aaa", "aaa", 0, 3, 0 }, /* simple case */ + { "aaa", "a", 0, 1, 0 }, /* start of string */ + { "aaa", "a", 2, 1, 2 }, /* end of string */ + { "aaa", "a", *p_basic_string_char_npos, 1, 2 }, /* off == npos */ + { "aaa", "z", 0, 1, *p_basic_string_char_npos } /* can't find */ + }; + + for(i=0; i