[CRT TEST][USER32_APITEST]
authorThomas Faber <thomas.faber@reactos.org>
Wed, 4 Jul 2012 17:33:56 +0000 (17:33 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Wed, 4 Jul 2012 17:33:56 +0000 (17:33 +0000)
- Add a test for sprintf/wsprintfA (mainly NULL buffer and string precision)

svn path=/trunk/; revision=56823

rostests/apitests/crt/crtdll_crt_apitest.cmake
rostests/apitests/crt/msvcrt_crt_apitest.cmake
rostests/apitests/crt/ntdll_crt_apitest.cmake
rostests/apitests/crt/sprintf.c [new file with mode: 0644]
rostests/apitests/crt/testlist.c
rostests/apitests/user32/CMakeLists.txt
rostests/apitests/user32/testlist.c
rostests/apitests/user32/wsprintf.c [new file with mode: 0644]

index 669f6d5..f739fb5 100644 (file)
@@ -454,7 +454,7 @@ list(APPEND SOURCE_CRTDLL
 #    signal.c
 #    sin.c
 #    sinh.c
-#    sprintf.c
+    sprintf.c
 #    sqrt.c
 #    srand.c
 #    sscanf.c
index 7e2f9aa..5c75c23 100644 (file)
@@ -1156,7 +1156,7 @@ list(APPEND SOURCE_MSVCRT
 #    signal.c
 #    sin.c
 #    sinh.c
-#    sprintf.c
+    sprintf.c
 #    sprintf_s.c
 #    sqrt.c
 #    srand.c
index c6fae82..3b3560e 100644 (file)
@@ -80,7 +80,7 @@ list(APPEND SOURCE_NTDLL
 #    pow.c
 #    qsort.c
 #    sin.c
-#    sprintf.c
+    sprintf.c
 #    sqrt.c
 #    sscanf.c
 #    strcat.c
diff --git a/rostests/apitests/crt/sprintf.c b/rostests/apitests/crt/sprintf.c
new file mode 100644 (file)
index 0000000..790f9b4
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * PROJECT:         ReactOS api tests
+ * LICENSE:         GPLv2+ - See COPYING in the top level directory
+ * PURPOSE:         Test for sprintf
+ * PROGRAMMER:      Thomas Faber <thfabba@gmx.de>
+ */
+
+#define WIN32_NO_STATUS
+#include <stdio.h>
+#include <wine/test.h>
+#include <tchar.h>
+#include <pseh/pseh2.h>
+#include <ndk/mmfuncs.h>
+#include <ndk/rtlfuncs.h>
+
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wformat"
+#pragma GCC diagnostic ignored "-Wformat-zero-length"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#endif
+
+#define StartSeh()              ExceptionStatus = STATUS_SUCCESS; _SEH2_TRY {
+#define EndSeh(ExpectedStatus)  } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExceptionStatus = _SEH2_GetExceptionCode(); } _SEH2_END; ok(ExceptionStatus == ExpectedStatus, "Exception %lx, expected %lx\n", ExceptionStatus, ExpectedStatus)
+
+static
+PVOID
+AllocateGuarded(
+    SIZE_T SizeRequested)
+{
+    NTSTATUS Status;
+    SIZE_T Size = PAGE_ROUND_UP(SizeRequested + PAGE_SIZE);
+    PVOID VirtualMemory = NULL;
+    PCHAR StartOfBuffer;
+
+    Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_RESERVE, PAGE_NOACCESS);
+
+    if (!NT_SUCCESS(Status))
+        return NULL;
+
+    Size -= PAGE_SIZE;
+    if (Size)
+    {
+        Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READWRITE);
+        if (!NT_SUCCESS(Status))
+        {
+            Size = 0;
+            Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE);
+            ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
+            return NULL;
+        }
+    }
+
+    StartOfBuffer = VirtualMemory;
+    StartOfBuffer += Size - SizeRequested;
+
+    return StartOfBuffer;
+}
+
+static
+VOID
+FreeGuarded(
+    PVOID Pointer)
+{
+    NTSTATUS Status;
+    PVOID VirtualMemory = (PVOID)PAGE_ROUND_DOWN((SIZE_T)Pointer);
+    SIZE_T Size = 0;
+
+    Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE);
+    ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
+}
+
+/* NOTE: This test is not only used for all the CRT apitests, but also for
+ *       user32's wsprintf. Make sure to test them all */
+START_TEST(sprintf)
+{
+    NTSTATUS ExceptionStatus;
+    int Length;
+    CHAR Buffer[128];
+    PCHAR String;
+
+    /* basic parameter tests */
+    StartSeh()
+        Length = sprintf(NULL, NULL);
+    EndSeh(STATUS_ACCESS_VIOLATION);
+
+    StartSeh()
+        Length = sprintf(NULL, "");
+        ok_int(Length, 0);
+#if defined(TEST_CRTDLL) || defined(TEST_USER32)
+    EndSeh(STATUS_ACCESS_VIOLATION);
+#else
+    EndSeh(STATUS_SUCCESS);
+#endif
+
+    StartSeh()
+        Length = sprintf(NULL, "Hello");
+        ok_int(Length, 5);
+#if defined(TEST_CRTDLL) || defined(TEST_USER32)
+    EndSeh(STATUS_ACCESS_VIOLATION);
+#else
+    EndSeh(STATUS_SUCCESS);
+#endif
+
+    /* some basic formats */
+    Length = sprintf(Buffer, "abcde");
+    ok_str(Buffer, "abcde");
+    ok_int(Length, 5);
+
+    Length = sprintf(Buffer, "%%");
+    ok_str(Buffer, "%");
+    ok_int(Length, 1);
+
+    Length = sprintf(Buffer, "%");
+    ok_str(Buffer, "");
+    ok_int(Length, 0);
+
+    Length = sprintf(Buffer, "%%%");
+    ok_str(Buffer, "%");
+    ok_int(Length, 1);
+
+    Length = sprintf(Buffer, "%d", 8);
+    ok_str(Buffer, "8");
+    ok_int(Length, 1);
+
+    Length = sprintf(Buffer, "%s", "hello");
+    ok_str(Buffer, "hello");
+    ok_int(Length, 5);
+
+    /* field width for %s */
+    Length = sprintf(Buffer, "%8s", "hello");
+    ok_str(Buffer, "   hello");
+    ok_int(Length, 8);
+
+    Length = sprintf(Buffer, "%4s", "hello");
+    ok_str(Buffer, "hello");
+    ok_int(Length, 5);
+
+    Length = sprintf(Buffer, "%-8s", "hello");
+    ok_str(Buffer, "hello   ");
+    ok_int(Length, 8);
+
+    Length = sprintf(Buffer, "%-5s", "hello");
+    ok_str(Buffer, "hello");
+    ok_int(Length, 5);
+
+    Length = sprintf(Buffer, "%0s", "hello");
+    ok_str(Buffer, "hello");
+    ok_int(Length, 5);
+
+    Length = sprintf(Buffer, "%-0s", "hello");
+    ok_str(Buffer, "hello");
+    ok_int(Length, 5);
+
+    /* TODO: wsprintf can't do * */
+#ifndef TEST_USER32
+    Length = sprintf(Buffer, "%*s", -8, "hello");
+    ok_str(Buffer, "hello   ");
+    ok_int(Length, 8);
+#endif
+
+    /* precision for %s */
+    Length = sprintf(Buffer, "%.s", "hello");
+    ok_str(Buffer, "");
+    ok_int(Length, 0);
+
+    Length = sprintf(Buffer, "%.0s", "hello");
+    ok_str(Buffer, "");
+    ok_int(Length, 0);
+
+    Length = sprintf(Buffer, "%.10s", "hello");
+    ok_str(Buffer, "hello");
+    ok_int(Length, 5);
+
+    Length = sprintf(Buffer, "%.5s", "hello");
+    ok_str(Buffer, "hello");
+    ok_int(Length, 5);
+
+    Length = sprintf(Buffer, "%.4s", "hello");
+    ok_str(Buffer, "hell");
+    ok_int(Length, 4);
+    
+#ifndef TEST_USER32
+    StartSeh()
+        Length = sprintf(Buffer, "%.*s", -1, "hello");
+        ok_str(Buffer, "hello");
+        ok_int(Length, 5);
+    EndSeh(STATUS_SUCCESS);
+#endif
+
+    String = AllocateGuarded(6);
+    if (!String)
+    {
+        skip("Guarded allocation failure\n");
+        return;
+    }
+
+    strcpy(String, "hello");
+    StartSeh()
+        Length = sprintf(Buffer, "%.8s", String);
+        ok_str(Buffer, "hello");
+        ok_int(Length, 5);
+    EndSeh(STATUS_SUCCESS);
+
+    StartSeh()
+        Length = sprintf(Buffer, "%.6s", String);
+        ok_str(Buffer, "hello");
+        ok_int(Length, 5);
+    EndSeh(STATUS_SUCCESS);
+
+    StartSeh()
+        Length = sprintf(Buffer, "%.5s", String);
+        ok_str(Buffer, "hello");
+        ok_int(Length, 5);
+    EndSeh(STATUS_SUCCESS);
+
+    StartSeh()
+        Length = sprintf(Buffer, "%.4s", String);
+        ok_str(Buffer, "hell");
+        ok_int(Length, 4);
+    EndSeh(STATUS_SUCCESS);
+
+    /* TODO: wsprintf can't do *, and also seems to use strlen despite a
+     * precision being given */
+#ifndef TEST_USER32
+    String[5] = '!';
+    StartSeh()
+        Length = sprintf(Buffer, "%.5s", String);
+        ok_str(Buffer, "hello");
+        ok_int(Length, 5);
+    EndSeh(STATUS_SUCCESS);
+
+    StartSeh()
+        Length = sprintf(Buffer, "%.6s", String);
+        ok_str(Buffer, "hello!");
+        ok_int(Length, 6);
+    EndSeh(STATUS_SUCCESS);
+
+    StartSeh()
+        Length = sprintf(Buffer, "%.*s", 5, String);
+        ok_str(Buffer, "hello");
+        ok_int(Length, 5);
+    EndSeh(STATUS_SUCCESS);
+
+    StartSeh()
+        Length = sprintf(Buffer, "%.*s", 6, String);
+        ok_str(Buffer, "hello!");
+        ok_int(Length, 6);
+    EndSeh(STATUS_SUCCESS);
+
+    /* both field width and precision */
+    StartSeh()
+        Length = sprintf(Buffer, "%8.5s", String);
+        ok_str(Buffer, "   hello");
+        ok_int(Length, 8);
+    EndSeh(STATUS_SUCCESS);
+
+    StartSeh()
+        Length = sprintf(Buffer, "%-*.6s", -8, String);
+        ok_str(Buffer, "hello!  ");
+        ok_int(Length, 8);
+    EndSeh(STATUS_SUCCESS);
+
+    StartSeh()
+        Length = sprintf(Buffer, "%*.*s", -8, 6, String);
+        ok_str(Buffer, "hello!  ");
+        ok_int(Length, 8);
+    EndSeh(STATUS_SUCCESS);
+#endif
+
+    FreeGuarded(String);
+}
index c3e317a..4c2546c 100644 (file)
@@ -5,10 +5,12 @@
 #define STANDALONE
 #include "wine/test.h"
 
+extern void func_sprintf(void);
 extern void func_strcpy(void);
 
 const struct test winetest_testlist[] =
 {
+    { "sprintf", func_sprintf },
     { "strcpy", func_strcpy },
 #if defined(TEST_CRTDLL) || defined(TEST_MSVCRT) || defined(TEST_STATIC_CRT)
     // ...
index aa4ada9..a83c34b 100644 (file)
@@ -1,8 +1,4 @@
 
-add_definitions(-D_DLL -D__USE_CRTIMP)
-
-set_rc_compiler()
-
 list(APPEND SOURCE
     helper.c
     DeferWindowPos.c
@@ -15,16 +11,17 @@ list(APPEND SOURCE
     RealGetWindowClass.c
     ScrollDC.c
     ScrollWindowEx.c
-    SetCursorPos.c
     SetActiveWindow.c
+    SetCursorPos.c
     SystemParametersInfo.c
     TrackMouseEvent.c
     WndProc.c
+    wsprintf.c
     testlist.c
     user32_apitest.rc)
 
 add_executable(user32_apitest ${SOURCE})
-target_link_libraries(user32_apitest wine)
+target_link_libraries(user32_apitest wine ${PSEH_LIB})
 set_module_type(user32_apitest win32cui)
 add_importlibs(user32_apitest gdi32 user32 msvcrt kernel32 ntdll)
 add_cd_file(TARGET user32_apitest DESTINATION reactos/bin FOR all)
index fef794d..f1d248f 100644 (file)
@@ -5,39 +5,41 @@
 #define STANDALONE
 #include "wine/test.h"
 
+extern void func_DeferWindowPos(void);
 extern void func_desktop(void);
+extern void func_GetIconInfo(void);
+extern void func_GetKeyState(void);
+extern void func_GetPeekMessage(void);
+extern void func_GetSystemMetrics(void);
 extern void func_InitializeLpkHooks(void);
 extern void func_RealGetWindowClass(void);
 extern void func_ScrollDC(void);
 extern void func_ScrollWindowEx(void);
-extern void func_GetSystemMetrics(void);
-extern void func_GetIconInfo(void);
-extern void func_GetPeekMessage(void);
-extern void func_DeferWindowPos(void);
-extern void func_GetKeyState(void);
-extern void func_SetCursorPos(void);
 extern void func_SetActiveWindow(void);
+extern void func_SetCursorPos(void);
 extern void func_SystemParametersInfo(void);
 extern void func_TrackMouseEvent(void);
 extern void func_WndProc(void);
+extern void func_wsprintf(void);
 
 const struct test winetest_testlist[] =
 {
+    { "desktop", func_desktop },
+    { "DeferWindowPos", func_DeferWindowPos },
+    { "GetIconInfo", func_GetIconInfo },
+    { "GetKeyState", func_GetKeyState },
+    { "GetPeekMessage", func_GetPeekMessage },
+    { "GetSystemMetrics", func_GetSystemMetrics },
     { "InitializeLpkHooks", func_InitializeLpkHooks },
     { "RealGetWindowClass", func_RealGetWindowClass },
     { "ScrollDC", func_ScrollDC },
     { "ScrollWindowEx", func_ScrollWindowEx },
-    { "GetSystemMetrics", func_GetSystemMetrics },
-    { "GetIconInfo", func_GetIconInfo },
-    { "GetPeekMessage", func_GetPeekMessage },
-    { "DeferWindowPos", func_DeferWindowPos },
-    { "desktop", func_desktop } ,
-    { "GetKeyState", func_GetKeyState },
-    { "SetCursorPos", func_SetCursorPos },
     { "SetActiveWindow", func_SetActiveWindow },
+    { "SetCursorPos", func_SetCursorPos },
     { "SystemParametersInfo", func_SystemParametersInfo },
     { "TrackMouseEvent", func_TrackMouseEvent },
     { "WndProc", func_WndProc },
+    { "wsprintf", func_wsprintf },
     { 0, 0 }
 };
 
diff --git a/rostests/apitests/user32/wsprintf.c b/rostests/apitests/user32/wsprintf.c
new file mode 100644 (file)
index 0000000..2c02580
--- /dev/null
@@ -0,0 +1,4 @@
+#define sprintf wsprintfA
+#define func_sprintf func_wsprintf
+#define TEST_USER32 1
+#include "../crt/sprintf.c"