Commit 15c6057c authored by Andrew Nguyen's avatar Andrew Nguyen Committed by Alexandre Julliard

shlwapi: Implement StrStrNIW.

parent 9bd13c93
...@@ -802,6 +802,7 @@ ...@@ -802,6 +802,7 @@
@ stdcall StrStrIA(str str) @ stdcall StrStrIA(str str)
@ stdcall StrStrIW(wstr wstr) @ stdcall StrStrIW(wstr wstr)
@ stdcall StrStrNW(wstr wstr long) @ stdcall StrStrNW(wstr wstr long)
@ stdcall StrStrNIW(wstr wstr long)
@ stdcall StrStrW(wstr wstr) @ stdcall StrStrW(wstr wstr)
@ stdcall StrToIntA(str) @ stdcall StrToIntA(str)
@ stdcall StrToIntExA(str long ptr) @ stdcall StrToIntExA(str long ptr)
......
...@@ -744,6 +744,41 @@ LPWSTR WINAPI StrStrNW(LPCWSTR lpFirst, LPCWSTR lpSrch, UINT cchMax) ...@@ -744,6 +744,41 @@ LPWSTR WINAPI StrStrNW(LPCWSTR lpFirst, LPCWSTR lpSrch, UINT cchMax)
} }
/************************************************************************* /*************************************************************************
* StrStrNIW [SHLWAPI.@]
*
* Find a substring within a string up to a given number of initial characters,
* ignoring case.
*
* PARAMS
* lpFirst [I] String to search in
* lpSrch [I] String to look for
* cchMax [I] Maximum number of initial search characters
*
* RETURNS
* The start of lpFirst within lpSrch, or NULL if not found.
*/
LPWSTR WINAPI StrStrNIW(LPCWSTR lpFirst, LPCWSTR lpSrch, UINT cchMax)
{
UINT i;
int len;
TRACE("(%s, %s, %u)\n", debugstr_w(lpFirst), debugstr_w(lpSrch), cchMax);
if (!lpFirst || !lpSrch || !*lpSrch || !cchMax)
return NULL;
len = strlenW(lpSrch);
for (i = cchMax; *lpFirst && (i > 0); i--, lpFirst++)
{
if (!strncmpiW(lpFirst, lpSrch, len))
return (LPWSTR)lpFirst;
}
return NULL;
}
/*************************************************************************
* StrToIntA [SHLWAPI.@] * StrToIntA [SHLWAPI.@]
* *
* Read a signed integer from a string. * Read a signed integer from a string.
......
...@@ -59,6 +59,7 @@ static HRESULT (WINAPI *pStrRetToBSTR)(STRRET*,void*,BSTR*); ...@@ -59,6 +59,7 @@ static HRESULT (WINAPI *pStrRetToBSTR)(STRRET*,void*,BSTR*);
static HRESULT (WINAPI *pStrRetToBufA)(STRRET*,LPCITEMIDLIST,LPSTR,UINT); static HRESULT (WINAPI *pStrRetToBufA)(STRRET*,LPCITEMIDLIST,LPSTR,UINT);
static HRESULT (WINAPI *pStrRetToBufW)(STRRET*,LPCITEMIDLIST,LPWSTR,UINT); static HRESULT (WINAPI *pStrRetToBufW)(STRRET*,LPCITEMIDLIST,LPWSTR,UINT);
static LPWSTR (WINAPI *pStrStrNW)(LPCWSTR,LPCWSTR,UINT); static LPWSTR (WINAPI *pStrStrNW)(LPCWSTR,LPCWSTR,UINT);
static LPWSTR (WINAPI *pStrStrNIW)(LPCWSTR,LPCWSTR,UINT);
static INT (WINAPIV *pwnsprintfA)(LPSTR,INT,LPCSTR, ...); static INT (WINAPIV *pwnsprintfA)(LPSTR,INT,LPCSTR, ...);
static INT (WINAPIV *pwnsprintfW)(LPWSTR,INT,LPCWSTR, ...); static INT (WINAPIV *pwnsprintfW)(LPWSTR,INT,LPCWSTR, ...);
static LPWSTR (WINAPI *pStrChrNW)(LPWSTR,WCHAR,UINT); static LPWSTR (WINAPI *pStrChrNW)(LPWSTR,WCHAR,UINT);
...@@ -1248,6 +1249,100 @@ static void test_StrStrNW(void) ...@@ -1248,6 +1249,100 @@ static void test_StrStrNW(void)
} }
} }
static void test_StrStrNIW(void)
{
static const WCHAR emptyW[] = {0};
static const WCHAR deadbeefW[] = {'D','e','A','d','B','e','E','f',0};
static const WCHAR deadW[] = {'D','e','A','d',0};
static const WCHAR dead_lowerW[] = {'d','e','a','d',0};
static const WCHAR adbeW[] = {'A','d','B','e',0};
static const WCHAR adbe_lowerW[] = {'a','d','b','e',0};
static const WCHAR beefW[] = {'B','e','E','f',0};
static const WCHAR beef_lowerW[] = {'b','e','e','f',0};
static const WCHAR cafeW[] = {'c','a','f','e',0};
const struct
{
const WCHAR *search;
const UINT count;
const WCHAR *expect;
} StrStrNIW_cases[] =
{
{emptyW, sizeof(deadbeefW)/sizeof(WCHAR), NULL},
{deadW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW},
{dead_lowerW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW},
{adbeW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW + 2},
{adbe_lowerW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW + 2},
{beefW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW + 4},
{beef_lowerW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW + 4},
{cafeW, sizeof(deadbeefW)/sizeof(WCHAR), NULL},
{beefW, 0, NULL},
{beefW, 1, NULL},
{beefW, 2, NULL},
{beefW, 3, NULL},
{beefW, 4, NULL},
{beefW, 5, deadbeefW + 4},
{beefW, 6, deadbeefW + 4},
{beefW, 7, deadbeefW + 4},
{beefW, 8, deadbeefW + 4},
{beefW, 9, deadbeefW + 4},
{beef_lowerW, 0, NULL},
{beef_lowerW, 1, NULL},
{beef_lowerW, 2, NULL},
{beef_lowerW, 3, NULL},
{beef_lowerW, 4, NULL},
{beef_lowerW, 5, deadbeefW + 4},
{beef_lowerW, 6, deadbeefW + 4},
{beef_lowerW, 7, deadbeefW + 4},
{beef_lowerW, 8, deadbeefW + 4},
{beef_lowerW, 9, deadbeefW + 4},
};
LPWSTR ret;
UINT i;
if (!pStrStrNIW)
{
win_skip("StrStrNIW() is not available\n");
return;
}
ret = pStrStrNIW(NULL, NULL, 0);
ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
ret = pStrStrNIW(NULL, NULL, 10);
ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
ret = pStrStrNIW(NULL, emptyW, 10);
ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
ret = pStrStrNIW(emptyW, NULL, 10);
ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
ret = pStrStrNIW(emptyW, emptyW, 10);
ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
for (i = 0; i < sizeof(StrStrNIW_cases)/sizeof(StrStrNIW_cases[0]); i++)
{
ret = pStrStrNIW(deadbeefW, StrStrNIW_cases[i].search, StrStrNIW_cases[i].count);
ok(ret == StrStrNIW_cases[i].expect,
"[%d] Expected StrStrNIW to return %p, got %p\n",
i, StrStrNIW_cases[i].expect, ret);
}
/* StrStrNIW accepts counts larger than the search string length but rejects
* counts larger than around 2G. The limit seems to change based on the
* caller executable itself. */
ret = pStrStrNIW(deadbeefW, beefW, 100);
ok(ret == deadbeefW + 4, "Expected StrStrNIW to return deadbeefW + 4, got %p\n", ret);
if (0)
{
ret = pStrStrNIW(deadbeefW, beefW, ~0U);
ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
}
}
START_TEST(string) START_TEST(string)
{ {
HMODULE hShlwapi; HMODULE hShlwapi;
...@@ -1279,6 +1374,7 @@ START_TEST(string) ...@@ -1279,6 +1374,7 @@ START_TEST(string)
pStrRetToBufA = (void *)GetProcAddress(hShlwapi, "StrRetToBufA"); pStrRetToBufA = (void *)GetProcAddress(hShlwapi, "StrRetToBufA");
pStrRetToBufW = (void *)GetProcAddress(hShlwapi, "StrRetToBufW"); pStrRetToBufW = (void *)GetProcAddress(hShlwapi, "StrRetToBufW");
pStrStrNW = (void *)GetProcAddress(hShlwapi, "StrStrNW"); pStrStrNW = (void *)GetProcAddress(hShlwapi, "StrStrNW");
pStrStrNIW = (void *)GetProcAddress(hShlwapi, "StrStrNIW");
pwnsprintfA = (void *)GetProcAddress(hShlwapi, "wnsprintfA"); pwnsprintfA = (void *)GetProcAddress(hShlwapi, "wnsprintfA");
pwnsprintfW = (void *)GetProcAddress(hShlwapi, "wnsprintfW"); pwnsprintfW = (void *)GetProcAddress(hShlwapi, "wnsprintfW");
...@@ -1323,6 +1419,7 @@ START_TEST(string) ...@@ -1323,6 +1419,7 @@ START_TEST(string)
test_StrStrIA(); test_StrStrIA();
test_StrStrIW(); test_StrStrIW();
test_StrStrNW(); test_StrStrNW();
test_StrStrNIW();
CoUninitialize(); CoUninitialize();
} }
...@@ -877,6 +877,7 @@ LPWSTR WINAPI StrStrIW(LPCWSTR,LPCWSTR); ...@@ -877,6 +877,7 @@ LPWSTR WINAPI StrStrIW(LPCWSTR,LPCWSTR);
#define StrStrI WINELIB_NAME_AW(StrStrI) #define StrStrI WINELIB_NAME_AW(StrStrI)
LPWSTR WINAPI StrStrNW(LPCWSTR,LPCWSTR,UINT); LPWSTR WINAPI StrStrNW(LPCWSTR,LPCWSTR,UINT);
LPWSTR WINAPI StrStrNIW(LPCWSTR,LPCWSTR,UINT);
int WINAPI StrToIntA(LPCSTR); int WINAPI StrToIntA(LPCSTR);
int WINAPI StrToIntW(LPCWSTR); int WINAPI StrToIntW(LPCWSTR);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment