#include <math.h>
#include <float.h>
+#define CONST_VTABLE
+
#include "windef.h"
#include "winbase.h"
#include "winsock.h"
/* Get a conversion function ptr, return if function not available */
#define CHECKPTR(func) p##func = (void*)GetProcAddress(hOleaut32, #func); \
- if (!p##func) { trace("function " # func " not available, not testing it\n"); return; }
+ if (!p##func) { win_skip("function " # func " not available, not testing it\n"); return; }
/* Have IRecordInfo data type? */
static int HAVE_OLEAUT32_RECORD = 0;
HRESULT res;
res = VarBstrFromBool(VARIANT_TRUE, LANG_USER_DEFAULT, VAR_LOCALBOOL, &bstr);
- ok(SUCCEEDED(res) && (lstrlenW(bstr) > 0),
+ ok(res == S_OK && (lstrlenW(bstr) > 0),
"Expected localized string for 'True'\n");
/* lstrcpyW / lstrcatW do not work on win95 */
memcpy(sz12_true, sz12, sizeof(sz12));
SysFreeString(bstr);
res = VarBstrFromBool(VARIANT_FALSE, LANG_USER_DEFAULT, VAR_LOCALBOOL, &bstr);
- ok(SUCCEEDED(res) && (lstrlenW(bstr) > 0),
+ ok(res == S_OK && (lstrlenW(bstr) > 0),
"Expected localized string for 'False'\n");
memcpy(sz12_false, sz12, sizeof(sz12));
if (bstr) memcpy(&sz12_false[2], bstr, SysStringByteLen(bstr) + sizeof(WCHAR));
VariantClear( &result );
}
+static int strcmp_wa(const WCHAR *strw, const char *stra)
+{
+ WCHAR buf[512];
+ MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(buf[0]));
+ return lstrcmpW(strw, buf);
+}
+
+#define test_bstr_var(a,b) _test_bstr_var(__LINE__,a,b)
+static void _test_bstr_var(unsigned line, const VARIANT *v, const char *str)
+{
+ ok_(__FILE__,line)(V_VT(v) == VT_BSTR, "unexpected vt=%d\n", V_VT(v));
+ if(V_VT(v) == VT_BSTR)
+ ok(!strcmp_wa(V_BSTR(v), str), "v=%s, expected %s\n", wine_dbgstr_w(V_BSTR(v)), str);
+}
static void test_VariantInit(void)
{
typedef struct
{
- const IUnknownVtbl *lpVtbl;
- LONG ref;
- LONG events;
+ IUnknown IUnknown_iface;
+ LONG ref;
+ LONG events;
} test_VariantClearImpl;
+static inline test_VariantClearImpl *impl_from_IUnknown(IUnknown *iface)
+{
+ return CONTAINING_RECORD(iface, test_VariantClearImpl, IUnknown_iface);
+}
+
static HRESULT WINAPI VC_QueryInterface(LPUNKNOWN iface,REFIID riid,LPVOID *ppobj)
{
- test_VariantClearImpl *This = (test_VariantClearImpl *)iface;
+ test_VariantClearImpl *This = impl_from_IUnknown(iface);
This->events |= 0x1;
return E_NOINTERFACE;
}
static ULONG WINAPI VC_AddRef(LPUNKNOWN iface) {
- test_VariantClearImpl *This = (test_VariantClearImpl *)iface;
+ test_VariantClearImpl *This = impl_from_IUnknown(iface);
This->events |= 0x2;
return InterlockedIncrement(&This->ref);
}
static ULONG WINAPI VC_Release(LPUNKNOWN iface) {
- test_VariantClearImpl *This = (test_VariantClearImpl *)iface;
+ test_VariantClearImpl *This = impl_from_IUnknown(iface);
/* static class, won't be freed */
This->events |= 0x4;
return InterlockedDecrement(&This->ref);
VC_Release,
};
-static test_VariantClearImpl test_myVariantClearImpl = {&test_VariantClear_vtbl, 1, 0};
+static test_VariantClearImpl test_myVariantClearImpl = {{&test_VariantClear_vtbl}, 1, 0};
static void test_VariantClear(void)
{
IUnknown *punk;
/* Crashes: Native does not test input for NULL, so neither does Wine */
- if (0) hres = VariantClear(NULL);
+ if (0)
+ VariantClear(NULL);
/* Only the type field is set, to VT_EMPTY */
V_VT(&v) = VT_UI4;
/* UNKNOWN */
V_VT(&v) = VT_UNKNOWN;
- V_UNKNOWN(&v) = (IUnknown*)&test_myVariantClearImpl;
+ V_UNKNOWN(&v) = &test_myVariantClearImpl.IUnknown_iface;
test_myVariantClearImpl.events = 0;
hres = VariantClear(&v);
ok(hres == S_OK, "ret %08x\n", hres);
ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
- ok(V_UNKNOWN(&v) == (IUnknown*)&test_myVariantClearImpl, "unknown %p\n", V_UNKNOWN(&v));
+ ok(V_UNKNOWN(&v) == &test_myVariantClearImpl.IUnknown_iface, "unknown %p\n", V_UNKNOWN(&v));
/* Check that Release got called, but nothing else */
ok(test_myVariantClearImpl.events == 0x4, "Unexpected call. events %08x\n", test_myVariantClearImpl.events);
/* UNKNOWN BYREF */
- punk = (IUnknown*)&test_myVariantClearImpl;
+ punk = &test_myVariantClearImpl.IUnknown_iface;
V_VT(&v) = VT_UNKNOWN | VT_BYREF;
V_UNKNOWNREF(&v) = &punk;
test_myVariantClearImpl.events = 0;
ok(test_myVariantClearImpl.events == 0x4, "Unexpected call. events %08x\n", test_myVariantClearImpl.events);
/* DISPATCH BYREF */
- punk = (IUnknown*)&test_myVariantClearImpl;
+ punk = &test_myVariantClearImpl.IUnknown_iface;
V_VT(&v) = VT_DISPATCH | VT_BYREF;
V_DISPATCHREF(&v) = (IDispatch**)&punk;
test_myVariantClearImpl.events = 0;
VariantInit(&vDst);
hres = VariantCopyInd(&vDst, &vSrc);
+ ok(hres == S_OK, "VariantCopyInd failed: 0x%08x\n", hres);
ok(V_VT(&vDst) == VT_UI1 && V_UI1(&vDst) == 0x77,
"CopyInd(deref): expected dst vt = VT_UI1, val 0x77, got %d|0x%X, 0x%2X\n",
V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK, V_UI1(&vDst));
VariantInit(&vDst);
hres = VariantCopyInd(&vDst, &vSrc);
+ ok(hres == S_OK, "VariantCopyInd failed: 0x%08x\n", hres);
ok(V_VT(&vDst) == VT_UI1 && V_UI1(&vDst) == 0x88,
"CopyInd(deref): expected dst vt = VT_UI1, val 0x77, got %d|0x%X, 0x%2X\n",
V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK, V_UI1(&vDst));
memset(&ud, 0, sizeof(ud));
res = pVarUdateFromDate(dt, flags, &ud);
- ok_(__FILE__,line)(r == res, "Wrong result %x/%x\n", r, res);
- if (SUCCEEDED(res))
- ok_(__FILE__,line)(ud.st.wYear == y && ud.st.wMonth == m && ud.st.wDay == d &&
- ud.st.wHour == h && ud.st.wMinute == mn && ud.st.wSecond == s &&
- ud.st.wMilliseconds == ms && ud.st.wDayOfWeek == dw && ud.wDayOfYear == dy,
- "%.16g expected %d,%d,%d,%d,%d,%d,%d %d %d, got %d,%d,%d,%d,%d,%d,%d %d %d\n",
- dt, d, m, y, h, mn, s, ms, dw, dy,
- ud.st.wDay, ud.st.wMonth, ud.st.wYear, ud.st.wHour, ud.st.wMinute,
- ud.st.wSecond, ud.st.wMilliseconds, ud.st.wDayOfWeek, ud.wDayOfYear );
+ ok_(__FILE__,line)(r == res && (res != S_OK || (ud.st.wYear == y && ud.st.wMonth == m && ud.st.wDay == d &&
+ ud.st.wHour == h && ud.st.wMinute == mn && ud.st.wSecond == s &&
+ ud.st.wMilliseconds == ms && ud.st.wDayOfWeek == dw && ud.wDayOfYear == dy)),
+ "%.16g expected res(%x) %d,%d,%d,%d,%d,%d,%d %d %d, got res(%x) %d,%d,%d,%d,%d,%d,%d %d %d\n",
+ dt, r, d, m, y, h, mn, s, ms, dw, dy,
+ res, ud.st.wDay, ud.st.wMonth, ud.st.wYear, ud.st.wHour, ud.st.wMinute,
+ ud.st.wSecond, ud.st.wMilliseconds, ud.st.wDayOfWeek, ud.wDayOfYear );
}
#define DT2UD(dt,flags,r,d,m,y,h,mn,s,ms,dw,dy) test_UdateFromDate(__LINE__,dt,flags,r,d,m,y,h,mn,s,ms,dw,dy)
DT2UD(29221.5,0,S_OK,1,1,1980,12,0,0,0,2,1); /* 12 AM */
DT2UD(29221.9888884444,0,S_OK,1,1,1980,23,44,0,0,2,1); /* 11:44 PM */
DT2UD(29221.7508765432,0,S_OK,1,1,1980,18,1,16,0,2,1); /* 6:18:02 PM */
+
+ /* Test handling of times on dates prior to the epoch */
+ DT2UD(-5.25,0,S_OK,25,12,1899,6,0,0,0,1,359);
+ DT2UD(-5.9999884259259,0,S_OK,25,12,1899,23,59,59,0,1,359);
+ /* This just demonstrates the non-linear nature of values prior to the epoch */
+ DT2UD(-4.0,0,S_OK,26,12,1899,0,0,0,0,2,360);
+ /* Numerical oddity: for 0.0 < x < 1.0, x and -x represent the same datetime */
+ DT2UD(-0.25,0,S_OK,30,12,1899,6,0,0,0,6,364);
+ DT2UD(0.25,0,S_OK,30,12,1899,6,0,0,0,6,364);
}
ud.st.wDayOfWeek = dw;
ud.wDayOfYear = dy;
res = pVarDateFromUdate(&ud, flags, &out);
- ok_(__FILE__,line)(r == res && (FAILED(r) || EQ_DOUBLE(out, dt)),
+ ok_(__FILE__,line)(r == res && (r != S_OK || EQ_DOUBLE(out, dt)),
"expected %x, %.16g, got %x, %.16g\n", r, dt, res, out);
}
#define UD2T(d,m,y,h,mn,s,ms,dw,dy,flags,r,dt) test_DateFromUDate(__LINE__,d,m,y,h,mn,s,ms,dw,dy,flags,r,dt)
UD2T(1,1,-1,18,1,16,0,0,0,0,S_OK,36161.75087962963); /* Test year -1 = 1999 */
UD2T(1,-1,1980,18,1,16,0,0,0,0,S_OK,29160.7508796296); /* Test month -1 = 11 */
UD2T(1,13,1980,0,0,0,0,2,1,0,S_OK,29587.0); /* Rolls fwd to 1/1/1981 */
+
+ /* Test handling of times on dates prior to the epoch */
+ UD2T(25,12,1899,6,0,0,0,1,359,0,S_OK,-5.25);
+ UD2T(25,12,1899,23,59,59,0,1,359,0,S_OK,-5.9999884259259);
+ /* This just demonstrates the non-linear nature of values prior to the epoch */
+ UD2T(26,12,1899,0,0,0,0,2,360,0,S_OK,-4.0);
+ /* for DATE values 0.0 < x < 1.0, x and -x represent the same datetime */
+ /* but when converting to DATE, prefer the positive versions */
+ UD2T(30,12,1899,6,0,0,0,6,364,0,S_OK,0.25);
}
static void test_st2dt(int line, WORD d, WORD m, WORD y, WORD h, WORD mn,
ST2DT(2,1,1980,0,0,0,0,TRUE,29222.0);
ST2DT(0,1,1980,0,0,0,0,TRUE,29220.0); /* Rolls back to 31 Dec 1899 */
ST2DT(1,13,1980,0,0,0,0,FALSE,29587.0); /* Fails on invalid month */
- ST2DT(31,12,90,0,0,0,0,TRUE,33238.0); /* year < 100 is 1900+year! */
+ ST2DT(31,12,90,0,0,0,0,TRUE,33238.0); /* 30 <= year < 100 is 1900+year */
+ ST2DT(1,1,30,0,0,0,0,TRUE,10959.0); /* 30 <= year < 100 is 1900+year */
+ ST2DT(1,1,29,0,0,0,0,TRUE,47119.0); /* 0 <= year < 30 is 2000+year */
+ ST2DT(1,1,0,0,0,0,0,TRUE,36526.0); /* 0 <= year < 30 is 2000+year */
}
static void test_dt2st(int line, double dt, INT r, WORD d, WORD m, WORD y,
{
static const WCHAR szNum0[] = {'0','\0' };
static const WCHAR szNum1[] = {'1','\0' };
+ static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' };
+ static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' };
HRESULT hres;
VARIANT v, exp, vDst;
DECIMAL *pdec = &V_DECIMAL(&v);
ok(V_VT(&v) == VT_BSTR && V_BSTR(&v) == szNum0, "VarNot(0): changed input\n");
VARNOT(BSTR,(BSTR)szNum1,I4,-2);
ok(V_VT(&v) == VT_BSTR && V_BSTR(&v) == szNum1, "VarNot(1): changed input\n");
+ VARNOT(BSTR, (BSTR)szTrue, BOOL, VARIANT_FALSE);
+ VARNOT(BSTR, (BSTR)szFalse, BOOL, VARIANT_TRUE);
V_VT(&v) = VT_DECIMAL;
S(U(*pdec)).sign = DECIMAL_NEG;
if (rightvt == VT_BSTR)
V_BSTR(&right) = rbstr;
V_VT(&result) = VT_EMPTY;
- resvt = VT_ERROR;
/* All extra flags produce errors */
if (ExtraFlags[i] == (VT_VECTOR|VT_BYREF|VT_RESERVED) ||
V_BSTR(&left) = lbstr;
V_VT(&right) = VT_BSTR;
V_BSTR(&right) = rbstr;
- hres = VarSub(&left, &right, &result);
+ hres = pVarSub(&left, &right, &result);
ok(hres == S_OK && V_VT(&result) == VT_R8,
"VarSub: expected coerced type VT_R8, got %s!\n", vtstr(V_VT(&result)));
ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 0),
V_VT(&right) = VT_UI1;
V_UI1(&right) = 9;
- hres = VarSub(&cy, &right, &result);
+ hres = pVarSub(&cy, &right, &result);
ok(hres == S_OK && V_VT(&result) == VT_CY,
"VarSub: expected coerced type VT_CY, got %s!\n", vtstr(V_VT(&result)));
hres = VarR8FromCy(V_CY(&result), &r);
ok(hres == S_OK && EQ_DOUBLE(r, 4702),
"VarSub: CY value %f, expected %f\n", r, (double)4720);
- hres = VarSub(&left, &dec, &result);
+ hres = pVarSub(&left, &dec, &result);
ok(hres == S_OK && V_VT(&result) == VT_DECIMAL,
"VarSub: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
hres = VarR8FromDec(&V_DECIMAL(&result), &r);
V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
test_Round( __LINE__, &v, deci, &exp )
+struct decimal_t {
+ BYTE scale;
+ BYTE sign;
+ ULONG Hi32;
+ ULONG Mid32;
+ ULONG Lo32;
+};
+
+struct decimal_round_t {
+ struct decimal_t source;
+ struct decimal_t ret;
+ int dec;
+};
+
+static const struct decimal_round_t decimal_round_data[] = {
+ {{ 0, DECIMAL_NEG, 0, 0, 1 }, { 0, DECIMAL_NEG, 0, 0, 1 }, 0},
+ {{ 0, 0, 0, 0, 1 }, { 0, 0, 0, 0, 1 }, 0},
+ {{ 2, 0, 0, 0, 155 }, { 0, 0, 0, 0, 16 }, 1},
+ {{ 2, 0, 0, 0, 155 }, { 1, 0, 0, 0, 2 }, 0},
+ {{ 2, 0, 0, 0, 199 }, { 1, 0, 0, 0, 20 }, 1},
+ {{ 2, 0, 0, 0, 199 }, { 2, 0, 0, 0, 199 }, 2},
+ {{ 2, DECIMAL_NEG, 0, 0, 199 }, { 2, DECIMAL_NEG, 0, 0, 199 }, 2},
+ {{ 2, DECIMAL_NEG, 0, 0, 55 }, { 2, DECIMAL_NEG, 0, 0, 6 }, 1},
+ {{ 2, 0, 0, 0, 55 }, { 2, 0, 0, 0, 6 }, 1}
+};
+
static void test_VarRound(void)
{
static WCHAR szNumMin[] = {'-','1','.','4','4','9','\0' };
VARIANT v, exp, vDst;
CY *pcy = &V_CY(&v);
char buff[8];
+ int i;
CHECKPTR(VarRound);
ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
"VarRound: expected 0x0,%d got 0x%X,%d\n", VT_NULL, hres, V_VT(&vDst));
- /* not yet implemented so no use testing yet
- todo_wine {
- DECIMAL *pdec = &V_DECIMAL(&v);
+ /* VT_DECIMAL */
+ for (i = 0; i < sizeof(decimal_round_data)/sizeof(struct decimal_round_t); i++)
+ {
+ const struct decimal_round_t *ptr = &decimal_round_data[i];
+ DECIMAL *pdec;
+
+ pdec = &V_DECIMAL(&v);
V_VT(&v) = VT_DECIMAL;
- S(U(*pdec)).sign = DECIMAL_NEG;
- S(U(*pdec)).scale = 0;
- pdec->Hi32 = 0;
- S1(U1(*pdec)).Mid32 = 0;
- S1(U1(*pdec)).Lo32 = 1;
- hres = pVarRound(&v,0,&vDst);
- ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL &&
- S(U(V_DECIMAL(&vDst))).sign == 0,
- "VarRound: expected 0x0,%d,0x00, got 0x%X,%d,%02x\n", VT_DECIMAL,
- hres, V_VT(&vDst), S(U(V_DECIMAL(&vDst))).sign);
-
- S(U(*pdec)).sign = 0;
- hres = pVarRound(&v,0,&vDst);
- ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL &&
- S(U(V_DECIMAL(&vDst))).sign == DECIMAL_NEG,
- "VarRound: expected 0x0,%d,0x7f, got 0x%X,%d,%02x\n", VT_DECIMAL,
- hres, V_VT(&vDst), S(U(V_DECIMAL(&vDst))).sign);
- }
- */
+ S(U(*pdec)).sign = ptr->source.sign;
+ S(U(*pdec)).scale = ptr->source.scale;
+ pdec->Hi32 = ptr->source.Hi32;
+ S1(U1(*pdec)).Mid32 = ptr->source.Mid32;
+ S1(U1(*pdec)).Lo32 = ptr->source.Lo32;
+ VariantInit(&vDst);
+ hres = pVarRound(&v, ptr->dec, &vDst);
+ todo_wine
+ ok(hres == S_OK, "%d: got 0x%08x\n", i, hres);
+ if (hres == S_OK)
+ {
+ ok(V_VT(&vDst) == VT_DECIMAL, "%d: got VT %d, expected VT_DECIMAL\n", i, V_VT(&vDst));
+ ok(S(U(V_DECIMAL(&vDst))).sign == ptr->ret.sign, "%d: got sign 0x%02x, expected 0x%02x\n",
+ i, S(U(V_DECIMAL(&vDst))).sign, ptr->ret.sign);
+ ok(V_DECIMAL(&vDst).Hi32 == ptr->ret.Hi32, "%d: got Hi32 %d, expected %d\n",
+ i, V_DECIMAL(&vDst).Hi32, ptr->ret.Hi32);
+ ok(S1(U1(V_DECIMAL(&vDst))).Mid32 == ptr->ret.Mid32, "%d: got Mid32 %d, expected %d\n",
+ i, S1(U1(V_DECIMAL(&vDst))).Mid32, ptr->ret.Mid32);
+ ok(S1(U1(V_DECIMAL(&vDst))).Lo32 == ptr->ret.Lo32, "%d: got Lo32 %d, expected %d\n",
+ i, S1(U1(V_DECIMAL(&vDst))).Lo32, ptr->ret.Lo32);
+ }
+ }
+ /* VT_CY */
V_VT(&v) = VT_CY;
pcy->int64 = 10000;
hres = pVarRound(&v,0,&vDst);
V_VT(&right) = VT_UI1;
V_UI1(&right) = 9;
- hres = VarMul(&cy, &right, &result);
+ hres = pVarMul(&cy, &right, &result);
ok(hres == S_OK && V_VT(&result) == VT_CY, "VarMul: expected coerced type VT_CY, got %s!\n", vtstr(V_VT(&result)));
hres = VarR8FromCy(V_CY(&result), &r);
ok(hres == S_OK && EQ_DOUBLE(r, 42399), "VarMul: CY value %f, expected %f\n", r, (double)42399);
- hres = VarMul(&left, &dec, &result);
+ hres = pVarMul(&left, &dec, &result);
ok(hres == S_OK && V_VT(&result) == VT_DECIMAL, "VarMul: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
hres = VarR8FromDec(&V_DECIMAL(&result), &r);
ok(hres == S_OK && EQ_DOUBLE(r, 46.2), "VarMul: DECIMAL value %f, expected %f\n", r, (double)46.2);
V_BSTR(&left) = lbstr;
V_VT(&right) = VT_BSTR;
V_BSTR(&right) = rbstr;
- hres = VarAdd(&left, &right, &result);
+ hres = pVarAdd(&left, &right, &result);
ok(hres == S_OK && V_VT(&result) == VT_BSTR, "VarAdd: expected coerced type VT_BSTR, got %s!\n", vtstr(V_VT(&result)));
hres = VarR8FromStr(V_BSTR(&result), 0, 0, &r);
ok(hres == S_OK && EQ_DOUBLE(r, 1212), "VarAdd: BSTR value %f, expected %f\n", r, (double)1212);
V_VT(&right) = VT_UI1;
V_UI1(&right) = 9;
- hres = VarAdd(&cy, &right, &result);
+ hres = pVarAdd(&cy, &right, &result);
ok(hres == S_OK && V_VT(&result) == VT_CY, "VarAdd: expected coerced type VT_CY, got %s!\n", vtstr(V_VT(&result)));
hres = VarR8FromCy(V_CY(&result), &r);
ok(hres == S_OK && EQ_DOUBLE(r, 4720), "VarAdd: CY value %f, expected %f\n", r, (double)4720);
- hres = VarAdd(&left, &dec, &result);
+ hres = pVarAdd(&left, &dec, &result);
ok(hres == S_OK && V_VT(&result) == VT_DECIMAL, "VarAdd: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
hres = VarR8FromDec(&V_DECIMAL(&result), &r);
ok(hres == S_OK && EQ_DOUBLE(r, -15.2), "VarAdd: DECIMAL value %f, expected %f\n", r, (double)-15.2);
SysFreeString(rbstr);
}
+static HRESULT (WINAPI *pVarCmp)(LPVARIANT,LPVARIANT,LCID,ULONG);
+static HRESULT (WINAPI *pVarCat)(LPVARIANT,LPVARIANT,LPVARIANT);
+
static void test_VarCat(void)
{
LCID lcid;
HRESULT hres;
HRESULT expected_error_num;
+ CHECKPTR(VarCat);
+
/* Set date format for testing */
lcid = LOCALE_USER_DEFAULT;
GetLocaleInfo(lcid,LOCALE_SSHORTDATE,orig_date_format,128);
V_I8(&right) = 0;
}
- hres = VarCat(&left, &right, &result);
+ hres = pVarCat(&left, &right, &result);
/* Determine the error code for the vt combination */
ok(hres == expected_error_num,
V_BSTR(&left) = SysAllocString(sz12);
V_BSTR(&right) = SysAllocString(sz34);
V_BSTR(&expected) = SysAllocString(sz1234);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
- ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
- "VarCat: VT_BSTR concat with VT_BSTR failed to return correct result\n");
+ if (pVarCmp)
+ ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
+ "VarCat: VT_BSTR concat with VT_BSTR failed to return correct result\n");
VariantClear(&left);
VariantClear(&right);
V_VT(&left) = VT_ERROR;
V_VT(&right) = VT_BSTR;
V_BSTR(&right) = SysAllocString(sz1234);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == DISP_E_TYPEMISMATCH, "VarCat should have returned DISP_E_TYPEMISMATCH instead of 0x%08x\n", hres);
ok(V_VT(&result) == VT_EMPTY,
"VarCat: VT_ERROR concat with VT_BSTR should have returned VT_EMPTY\n");
V_VT(&left) = VT_BSTR;
V_VT(&right) = VT_ERROR;
V_BSTR(&left) = SysAllocString(sz1234);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == DISP_E_TYPEMISMATCH, "VarCat should have returned DISP_E_TYPEMISMATCH instead of 0x%08x\n", hres);
ok(V_VT(&result) == VT_EMPTY,
"VarCat: VT_BSTR concat with VT_ERROR should have returned VT_EMPTY\n");
V_INT(&left) = 12;
V_BOOL(&right) = TRUE;
V_BSTR(&expected) = SysAllocString(sz12_true);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
- hres = VarCmp(&result,&expected,lcid,0);
- ok(hres == VARCMP_EQ, "Expected VARCMP_EQ, got %08x for %s, %s\n",
- hres, variantstr(&result), variantstr(&expected));
+ if (pVarCmp)
+ {
+ hres = pVarCmp(&result,&expected,lcid,0);
+ ok(hres == VARCMP_EQ, "Expected VARCMP_EQ, got %08x for %s, %s\n",
+ hres, variantstr(&result), variantstr(&expected));
+ }
VariantClear(&left);
VariantClear(&right);
V_INT(&left) = 12;
V_BOOL(&right) = FALSE;
V_BSTR(&expected) = SysAllocString(sz12_false);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
- hres = VarCmp(&result,&expected,lcid,0);
- ok(hres == VARCMP_EQ, "Expected VARCMP_EQ, got %08x for %s, %s\n",
- hres, variantstr(&result), variantstr(&expected));
+ if (pVarCmp)
+ {
+ hres = pVarCmp(&result,&expected,lcid,0);
+ ok(hres == VARCMP_EQ, "Expected VARCMP_EQ, got %08x for %s, %s\n",
+ hres, variantstr(&result), variantstr(&expected));
+ }
VariantClear(&left);
VariantClear(&right);
V_INT(&left) = 12;
V_INT(&right) = 34;
V_BSTR(&expected) = SysAllocString(sz1234);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
- ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
- "VarCat: NUMBER concat with NUMBER returned incorrect result\n");
+ if (pVarCmp)
+ ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
+ "VarCat: NUMBER concat with NUMBER returned incorrect result\n");
VariantClear(&left);
VariantClear(&right);
V_VT(&right) = VT_BSTR;
V_INT(&left) = 12;
V_BSTR(&right) = SysAllocString(sz34);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
- ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
- "VarCat: NUMBER concat with VT_BSTR, incorrect result\n");
+ if (pVarCmp)
+ ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
+ "VarCat: NUMBER concat with VT_BSTR, incorrect result\n");
VariantClear(&left);
VariantClear(&right);
V_VT(&right) = VT_INT;
V_BSTR(&left) = SysAllocString(sz12);
V_INT(&right) = 34;
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
- ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
- "VarCat: VT_BSTR concat with NUMBER, incorrect result\n");
+ if (pVarCmp)
+ ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
+ "VarCat: VT_BSTR concat with NUMBER, incorrect result\n");
VariantClear(&left);
VariantClear(&right);
V_DATE(&right) = 29494.0;
V_BSTR(&expected)= SysAllocString(sz12_date);
V_BSTR(&expected_broken)= SysAllocString(sz12_date_broken);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
- ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ ||
- broken(VarCmp(&result,&expected_broken,lcid,0) == VARCMP_EQ), /* Some W98 and NT4 (intermittent) */
- "VarCat: VT_BSTR concat with VT_DATE returned incorrect result\n");
+ if (pVarCmp)
+ ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ ||
+ broken(pVarCmp(&result,&expected_broken,lcid,0) == VARCMP_EQ), /* Some W98 and NT4 (intermittent) */
+ "VarCat: VT_BSTR concat with VT_DATE returned incorrect result\n");
VariantClear(&left);
VariantClear(&right);
V_BSTR(&right) = SysAllocString(sz12);
V_BSTR(&expected)= SysAllocString(date_sz12);
V_BSTR(&expected_broken)= SysAllocString(date_sz12_broken);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
- ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ ||
- broken(VarCmp(&result,&expected_broken,lcid,0) == VARCMP_EQ), /* Some W98 and NT4 (intermittent) */
- "VarCat: VT_DATE concat with VT_BSTR returned incorrect result\n");
+ if (pVarCmp)
+ ok(pVarCmp(&result,&expected,lcid,0) == VARCMP_EQ ||
+ broken(pVarCmp(&result,&expected_broken,lcid,0) == VARCMP_EQ), /* Some W98 and NT4 (intermittent) */
+ "VarCat: VT_DATE concat with VT_BSTR returned incorrect result\n");
VariantClear(&left);
VariantClear(&right);
V_BSTR(&left) = SysAllocString(sz_empty);
V_BSTR(&right) = SysAllocString(sz_empty);
V_BSTR(&expected)= SysAllocString(sz_empty);
- hres = VarCat(&left,&right,&result);
+ hres = pVarCat(&left,&right,&result);
ok(hres == S_OK, "VarCat failed with error 0x%08x\n", hres);
- ok(VarCmp(&result,&left,lcid,0) == VARCMP_EQ,
- "VarCat: EMPTY concat with EMPTY did not return empty VT_BSTR\n");
+ if (pVarCmp)
+ ok(pVarCmp(&result,&left,lcid,0) == VARCMP_EQ,
+ "VarCat: EMPTY concat with EMPTY did not return empty VT_BSTR\n");
/* Restore original date format settings */
SetLocaleInfo(lcid,LOCALE_SSHORTDATE,orig_date_format);
VariantClear(&right);
VariantClear(&result);
VariantClear(&expected);
+
+ /* Test boolean conversion */
+ V_VT(&left) = VT_BOOL;
+ V_BOOL(&left) = VARIANT_TRUE;
+ V_VT(&right) = VT_BSTR;
+ V_BSTR(&right) = SysAllocStringLen(NULL,0);
+ hres = pVarCat(&left, &right, &result);
+ ok(hres == S_OK, "VarCat failed: %08x\n", hres);
+ if(!strcmp_wa(V_BSTR(&result), "True")) {
+ V_VT(&right) = VT_BOOL;
+ V_BOOL(&right) = 100;
+ hres = pVarCat(&left, &right, &result);
+ ok(hres == S_OK, "VarCat failed: %08x\n", hres);
+ test_bstr_var(&result, "TrueTrue");
+ VariantClear(&result);
+
+ V_BOOL(&right) = VARIANT_FALSE;
+ hres = pVarCat(&left, &right, &result);
+ ok(hres == S_OK, "VarCat failed: %08x\n", hres);
+ test_bstr_var(&result, "TrueFalse");
+ VariantClear(&result);
+ }else {
+ skip("Got %s as True, assuming non-English locale\n", wine_dbgstr_w(V_BSTR(&result)));
+ }
}
static HRESULT (WINAPI *pVarAnd)(LPVARIANT,LPVARIANT,LPVARIANT);
SysFreeString(false_str);
}
-static HRESULT (WINAPI *pVarCmp)(LPVARIANT,LPVARIANT,LCID,ULONG);
-
static void test_cmp( int line, LCID lcid, UINT flags, VARIANT *left, VARIANT *right, HRESULT result )
{
HRESULT hres;
+ CHECKPTR(VarCmp);
+
hres = pVarCmp(left,right,lcid,flags);
ok_(__FILE__,line)(hres == result, "VarCmp(%s,%s): expected 0x%x, got hres=0x%x\n",
variantstr(left), variantstr(right), result, hres );
V_VT(&right) = VT_I8;
V_UI1(&right) = 2;
- hres = VarIdiv(&cy, &cy, &result);
+ hres = pVarIdiv(&cy, &cy, &result);
ok(hres == S_OK && V_VT(&result) == VT_I4,
"VARIDIV: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
S_OK, hres, vtstr(V_VT(&result)));
if (HAVE_OLEAUT32_I8)
{
- hres = VarIdiv(&cy, &right, &result);
+ hres = pVarIdiv(&cy, &right, &result);
ok(hres == S_OK && V_VT(&result) == VT_I8,
"VARIDIV: expected coerced hres 0x%X type VT_I8, got hres 0x%X type %s!\n",
S_OK, hres, vtstr(V_VT(&result)));
(DWORD)(V_I8(&result) >>32), (DWORD)V_I8(&result), 5000);
}
- hres = VarIdiv(&left, &cy, &result);
+ hres = pVarIdiv(&left, &cy, &result);
ok(hres == S_OK && V_VT(&result) == VT_I4,
"VARIDIV: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
S_OK, hres, vtstr(V_VT(&result)));
ok(hres == S_OK && V_I4(&result) == 0,
"VARIDIV: CY value %d, expected %d\n", V_I4(&result), 0);
- hres = VarIdiv(&left, &dec, &result);
+ hres = pVarIdiv(&left, &dec, &result);
ok(hres == S_OK && V_VT(&result) == VT_I4,
"VARIDIV: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
S_OK, hres, vtstr(V_VT(&result)));
ok(hres == S_OK && V_I4(&result) == 50,
"VARIDIV: DECIMAL value %d, expected %d\n", V_I4(&result), 50);
- hres = VarIdiv(&dec, &dec, &result);
+ hres = pVarIdiv(&dec, &dec, &result);
ok(hres == S_OK && V_VT(&result) == VT_I4,
"VARIDIV: expected coerced hres 0x%X type VT_I4, got hres 0x%X type %s!\n",
S_OK, hres, vtstr(V_VT(&result)));
if (HAVE_OLEAUT32_I8)
{
- hres = VarIdiv(&dec, &right, &result);
+ hres = pVarIdiv(&dec, &right, &result);
ok(hres == S_OK && V_VT(&result) == VT_I8,
"VARIDIV: expected coerced hres 0x%X type VT_I8, got hres 0x%X type %s!\n",
S_OK, hres, vtstr(V_VT(&result)));
test_VarEqv();
test_VarMul();
test_VarAdd();
+ test_VarCmp(); /* Before test_VarCat() which needs VarCmp() */
test_VarCat();
- test_VarCmp();
test_VarAnd();
test_VarDiv();
test_VarIdiv();