wsprintf.c 8.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
 /* Unit test suite for the wsprintf functions
 *
 * Copyright 2002 Bill Medland
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 19
 */

20 21
#include <stdarg.h>

22
#include "wine/test.h"
23
#include "windef.h"
24 25
#include "winbase.h"
#include "winuser.h"
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
#include "winnls.h"

static const struct
{
    const char *fmt;
    ULONGLONG value;
    const char *res;
} i64_formats[] =
{
    { "%I64X", ((ULONGLONG)0x12345 << 32) | 0x67890a, "123450067890A" },
    { "%I32X", ((ULONGLONG)0x12345 << 32) | 0x67890a, "67890A" },
    { "%I64d", (ULONGLONG)543210 * 1000000, "543210000000" },
    { "%I64X", (LONGLONG)-0x12345, "FFFFFFFFFFFEDCBB" },
    { "%I32x", (LONGLONG)-0x12345, "fffedcbb" },
    { "%I64u", (LONGLONG)-123, "18446744073709551493" },
    { "%Id",   (LONGLONG)-12345, "-12345" },
#ifdef _WIN64
    { "%Ix",   ((ULONGLONG)0x12345 << 32) | 0x67890a, "123450067890a" },
    { "%Ix",   (LONGLONG)-0x12345, "fffffffffffedcbb" },
    { "%p",    (LONGLONG)-0x12345, "FFFFFFFFFFFEDCBB" },
#else
    { "%Ix",   ((ULONGLONG)0x12345 << 32) | 0x67890a, "67890a" },
    { "%Ix",   (LONGLONG)-0x12345, "fffedcbb" },
    { "%p",    (LONGLONG)-0x12345, "FFFEDCBB" },
#endif
};
52

53
static void wsprintfATest(void)
54
{
55
    char buf[25], star[4], partial[4];
56 57 58
    static const WCHAR starW[] = L"\x2606";
    static const WCHAR fffeW[] = L"\xfffe";
    static const WCHAR wineW[] = L"\xd83c\xdf77"; /* U+1F377: wine glass */
59 60 61 62 63 64 65
    const struct {
        const void *input;
        const char *fmt;
        const char *str;
        int rc;
    }
    testcase[] = {
66 67 68 69 70 71
        { starW, "%.1S", partial, 1 },
        { starW, "%.2S", star,    2 },
        { starW, "%.3S", star,    2 },
        { fffeW, "%.1S", "?",     1 },
        { fffeW, "%.2S", "?",     1 },
        { wineW, "%.2S", "??",    2 },
72
        { star,  "%.1s", partial, 1 },
73 74 75
        { (void *)0x2606, "%2C",  star,    2 },
        { (void *)0xfffd, "%C",   "?",     1 },
        { (void *)0xe199, "%2c",  " \x99", 2 },
76 77
    };
    CPINFO cpinfo;
78
    unsigned int i;
79
    int rc;
80

81
    rc=wsprintfA(buf, "%010ld", -1);
82
    ok(rc == 10, "wsprintfA length failure: rc=%d error=%d\n",rc,GetLastError());
83
    ok((lstrcmpA(buf, "-000000001") == 0),
84
       "wsprintfA zero padded negative value failure: buf=[%s]\n",buf);
85 86 87 88 89 90
    rc = wsprintfA(buf, "%I64X", (ULONGLONG)0);
    if (rc == 4 && !lstrcmpA(buf, "I64X"))
    {
        win_skip( "I64 formats not supported\n" );
        return;
    }
91
    for (i = 0; i < ARRAY_SIZE(i64_formats); i++)
92 93 94 95 96
    {
        rc = wsprintfA(buf, i64_formats[i].fmt, i64_formats[i].value);
        ok(rc == strlen(i64_formats[i].res), "%u: wsprintfA length failure: rc=%d\n", i, rc);
        ok(!strcmp(buf, i64_formats[i].res), "%u: wrong result [%s]\n", i, buf);
    }
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121

    if (!GetCPInfo(CP_ACP, &cpinfo) || cpinfo.MaxCharSize <= 1)
    {
        skip("Multi-byte wsprintfA test isn't available for the current codepage\n");
        return;
    }

    rc = WideCharToMultiByte(CP_ACP, 0, starW, -1, star, sizeof(star), NULL, NULL);
    ok(rc == 3, "unexpected rc, got %d\n", rc);
    partial[0] = star[0];
    partial[1] = '\0';

    for (i = 0; i < ARRAY_SIZE(testcase); i++)
    {
        memset(buf, 0x11, sizeof(buf));
        rc = wsprintfA(buf, testcase[i].fmt, testcase[i].input);

        ok(rc == testcase[i].rc,
           "%u: expected %d, got %d\n",
           i, testcase[i].rc, rc);

        ok(!strcmp(buf, testcase[i].str),
           "%u: expected %s, got %s\n",
           i, wine_dbgstr_a(testcase[i].str), wine_dbgstr_an(buf, rc));
    }
122 123
}

124 125 126 127 128 129 130 131 132
static WCHAR my_btowc(BYTE c)
{
    WCHAR wc;
    if (!IsDBCSLeadByte(c) &&
        MultiByteToWideChar(CP_ACP, 0, (const char *)&c, 1, &wc, 1) > 0)
        return wc;
    return 0;
}

133
static void wsprintfWTest(void)
134
{
135 136
    static const WCHAR stars[] = L"*\x2606\x2605";
    WCHAR def_spc[] = L"*?\x2605 ";
137
    WCHAR buf[25], fmt[25], res[25], wcA1, wc99;
138 139 140 141 142 143 144 145
    char stars_mb[8], partial00[8], partialFF[8];
    const struct {
        const char *input;
        const WCHAR *fmt;
        const WCHAR *str;
        int rc;
    }
    testcase[] = {
146 147 148
        { stars_mb, L"%.3S", stars, 3 },
        { partial00, L"%-4S", L"*\0  ", 4 },
        { partialFF, L"%-4S", def_spc, 4 },
149 150
    };
    CPINFOEXW cpinfoex;
151
    unsigned int i;
152 153
    int rc;

154
    rc=wsprintfW(buf, L"%010ld", -1);
155
    if (rc==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
Paul Vriens's avatar
Paul Vriens committed
156
    {
157
        win_skip("wsprintfW is not implemented\n");
158
        return;
Paul Vriens's avatar
Paul Vriens committed
159
    }
160
    ok(rc == 10, "wsPrintfW length failure: rc=%d error=%d\n",rc,GetLastError());
161
    ok((lstrcmpW(buf, L"-000000001") == 0),
162
       "wsprintfW zero padded negative value failure\n");
163 164
    rc = wsprintfW(buf, L"%I64x", (ULONGLONG)0 );
    if (rc == 4 && !lstrcmpW(buf, L"I64x"))
165 166 167 168
    {
        win_skip( "I64 formats not supported\n" );
        return;
    }
169
    for (i = 0; i < ARRAY_SIZE(i64_formats); i++)
170
    {
171 172
        MultiByteToWideChar( CP_ACP, 0, i64_formats[i].fmt, -1, fmt, ARRAY_SIZE(fmt));
        MultiByteToWideChar( CP_ACP, 0, i64_formats[i].res, -1, res, ARRAY_SIZE(res));
173 174 175 176
        rc = wsprintfW(buf, fmt, i64_formats[i].value);
        ok(rc == lstrlenW(res), "%u: wsprintfW length failure: rc=%d\n", i, rc);
        ok(!lstrcmpW(buf, res), "%u: wrong result [%s]\n", i, wine_dbgstr_w(buf));
    }
177

178 179 180 181 182 183 184 185 186 187 188 189
    rc = wsprintfW(buf, L"%2c", L'*');
    ok(rc == 2, "expected 2, got %d\n", rc);
    ok(buf[0] == L' ', "expected \\x0020, got \\x%04x\n", buf[0]);
    ok(buf[1] == L'*', "expected \\x%04x, got \\x%04x\n", L'*', buf[1]);

    rc = wsprintfW(buf, L"%c", L'\x2605');
    ok(rc == 1, "expected 1, got %d\n", rc);
    ok(buf[0] == L'\x2605', "expected \\x%04x, got \\x%04x\n", L'\x2605', buf[0]);

    wcA1 = my_btowc(0xA1);
    rc = wsprintfW(buf, L"%C", 0xA1);
    ok(rc == 1, "expected 1, got %d\n", rc);
190
    ok(buf[0] == wcA1, "expected \\x%04x, got \\x%04x\n", wcA1, buf[0]);
191 192 193

    rc = wsprintfW(buf, L"%C", 0x81A1);
    ok(rc == 1, "expected 1, got %d\n", rc);
194
    ok(buf[0] == wcA1, "expected \\x%04x, got \\x%04x\n", wcA1, buf[0]);
195 196 197 198 199

    wc99 = my_btowc(0x99);
    rc = wsprintfW(buf, L"%2C", 0xe199);
    ok(rc == 2, "expected 1, got %d\n", rc);
    ok(buf[0] == L' ', "expected \\x0020, got \\x%04x\n", buf[0]);
200
    ok(buf[1] == wc99, "expected \\x%04x, got \\x%04x\n", wc99, buf[1]);
201

202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
    if (!GetCPInfoExW(CP_ACP, 0, &cpinfoex) || cpinfoex.MaxCharSize <= 1)
    {
        skip("Multi-byte wsprintfW test isn't available for the current codepage\n");
        return;
    }
    def_spc[1] = cpinfoex.UnicodeDefaultChar;

    rc = WideCharToMultiByte(CP_ACP, 0, stars, -1, stars_mb, sizeof(stars_mb), NULL, NULL);
    ok(rc == 6, "expected 6, got %d\n", rc);
    strcpy(partial00, stars_mb);
    partial00[2] = '\0';
    strcpy(partialFF, stars_mb);
    partialFF[2] = 0xff;

    for (i = 0; i < ARRAY_SIZE(testcase); i++)
    {
        memset(buf, 0x11, sizeof(buf));
        rc = wsprintfW(buf, testcase[i].fmt, testcase[i].input);

        ok(rc == testcase[i].rc,
           "%u: expected %d, got %d\n",
           i, testcase[i].rc, rc);

225
        ok(!memcmp(buf, testcase[i].str, (testcase[i].rc + 1) * sizeof(WCHAR)),
226 227 228 229
           "%u: expected %s, got %s\n", i,
           wine_dbgstr_wn(testcase[i].str, testcase[i].rc + 1),
           wine_dbgstr_wn(buf, rc + 1));
    }
230 231
}

232
/* Test if the CharUpper / CharLower functions return true 16 bit results,
233
   if the input is a 16 bit input value. */
234 235 236

static void CharUpperTest(void)
{
237 238
    INT_PTR i, out;
    BOOL failed = FALSE;
239 240 241

    for (i=0;i<256;i++)
    	{
242
	out = (INT_PTR)CharUpperA((LPSTR)i);
243 244
	if ((out >> 16) != 0)
	   {
245
           failed = TRUE;
246 247 248
	   break;
	   }
	}
249
    ok(!failed,"CharUpper failed - 16bit input (0x%0lx) returned 32bit result (0x%0lx)\n",i,out);
250 251 252 253
}

static void CharLowerTest(void)
{
254 255
    INT_PTR i, out;
    BOOL failed = FALSE;
256 257 258

    for (i=0;i<256;i++)
    	{
259
	out = (INT_PTR)CharLowerA((LPSTR)i);
260 261
	if ((out >> 16) != 0)
	   {
262
           failed = TRUE;
263 264 265
	   break;
	   }
	}
266
    ok(!failed,"CharLower failed - 16bit input (0x%0lx) returned 32bit result (0x%0lx)\n",i,out);
267 268 269
}


270 271
START_TEST(wsprintf)
{
272 273
    wsprintfATest();
    wsprintfWTest();
274 275
    CharUpperTest();
    CharLowerTest();
276
}