From 1ee1b476a970097b4239ff4547e572b177e6acb3 Mon Sep 17 00:00:00 2001 From: Austin Lund Date: Mon, 30 Jun 2008 15:11:47 +1000 Subject: [PATCH] richedit: Added tests for TxSetText and TxGetText in txtsrv.c. --- dlls/riched20/tests/txtsrv.c | 113 ++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 113 insertions(+), 0 deletions(-) diff --git a/dlls/riched20/tests/txtsrv.c b/dlls/riched20/tests/txtsrv.c index 3b686c4..6e82f08 100644 --- a/dlls/riched20/tests/txtsrv.c +++ b/dlls/riched20/tests/txtsrv.c @@ -33,6 +33,75 @@ #include #include +/* Implement the undo of the thiscall calling convention + * + * This one is so god damn evil but it WORKS! + * + * This sets up the stack in such a way that the function pointer is + * set on %eax, bar is on %edx (but bar isn't needed, and this is not + * done here), and finally %ecx to This. + * + * "This" was the whole trouble maker since you're not supposed to + * call that, even windows methods won't let you do that in C. + * + * MSVC isn't supported, but who cares? If you want to call them there + * just create a REAL C++ interface to test with. + * + * to recap: + * ITextServices_XXX(iface, ..) becomes: + * + * First define this: + * extern HRESULT WINAPI fnTextSrv_XXX(LPVOID function, + * ITextServices *iface, ........ ); + * + * __ASM_GLOBAL_FUNC(fnTextSrv_XXX, STDCALL_TO_THISCALL) + * + * Then call: + * fnTextSrv_XXX(iface->lpVtbl->XXX, iface, ..... ); + * + * This is only needed for i386. Therefore THISCALL_NEEDED is defined + * for i386 and if it is not defined then the same wrapper just calls + * the function without the thiscall code. + * + */ + +#ifdef __i386__ + +#define STDCALL_TO_THISCALL \ + "movl 0x8(%esp), %ecx\n\t" \ + "push %ebx\n\t" \ + "movl 0x4(%esp),%ebx\n\t" \ + "movl %ebx,0xc(%esp)\n\t" \ + "popl %ebx\n\t" \ + "popl %eax\n\t" \ + "popl %eax\n\t" \ + "jmp *%eax" + +#define THISCALL_NEEDED + +#endif + +/* ITextServices functions used are now wrapped with this construct. */ + +#ifdef THISCALL_NEEDED +extern HRESULT WINAPI fnTextSrv_TxGetText(LPVOID function, + ITextServices *iface, + BSTR* pbstrText); +__ASM_GLOBAL_FUNC(fnTextSrv_TxGetText, STDCALL_TO_THISCALL); +#else +#define fnTextSrv_TxGetText(f, iface, pbstrText) f(iface, pbstrText) +#endif + + +#ifdef THISCALL_NEEDED +extern HRESULT WINAPI fnTextSrv_TxSetText(LPVOID function, + ITextServices *iface, + LPCTSTR pszText); +__ASM_GLOBAL_FUNC(fnTextSrv_TxSetText, STDCALL_TO_THISCALL); +#else +#define fnTextSrv_TxSetText(f, iface, pszText) f(iface, pszText) +#endif + /************************************************************************/ /* ITextHost implementation for conformance testing. */ @@ -514,8 +583,52 @@ BOOL init_texthost() { return TRUE; } +/* Test TxSetText whilst actually setting the text. */ +void TEST_TxSetText(LPCTSTR newtext) { + HRESULT result; + todo_wine { + result = fnTextSrv_TxSetText(txtserv->lpVtbl->TxSetText, + txtserv,newtext); + trace("Called TxSetText(%p) on (%p): 0x%08x\n", + newtext, txtserv, result); + ok(result == S_OK, "TxSetText failed\n"); + } +} + +/* Test TxGetText and actually retrieve the text. */ +LPCTSTR TEST_TxGetText() { + LPCTSTR rettext; + HRESULT result; + todo_wine { + result = fnTextSrv_TxGetText(txtserv->lpVtbl->TxGetText, + txtserv,(BSTR*)&rettext); + trace("Called TxGetText(%p) on (%p): 0x%08x\n", + rettext, txtserv, result); + ok(result == S_OK, "TxSetText failed\n"); + } + return rettext; +} + +/* Simple test that sets the text then immediately retrives it. The + * result is compared with the original. */ +void TEST_TxSetGetText(LPCTSTR newtext) { + LPCTSTR cmptext; + + todo_wine { + TEST_TxSetText(newtext); + cmptext = TEST_TxGetText(); + ok(StrCmp(newtext,cmptext) == 0, "String not returned right\n"); + } +} + START_TEST( txtsrv ) { + static const WCHAR newtextw[] = + {'A','B','C','D','E','F','G','H','I','J','K','L','M', + 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0}; + if (!init_texthost()) return; + + TEST_TxSetGetText((LPCTSTR)newtextw); } -- 1.5.4.3