oleaut32: Conformance test and patch for VarCat.
This commit is contained in:
parent
ed9848930b
commit
700adac9ac
|
@ -2,6 +2,7 @@
|
|||
* VARIANT test program
|
||||
*
|
||||
* Copyright 1998 Jean-Claude Cote
|
||||
* Copyright 2006 Google (Benjamin Arai)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -5093,6 +5094,323 @@ static void test_VarAdd(void)
|
|||
SysFreeString(rbstr);
|
||||
}
|
||||
|
||||
static void test_VarCat(void)
|
||||
{
|
||||
LCID lcid;
|
||||
VARIANT left, right, result, expected;
|
||||
static const WCHAR sz12[] = {'1','2','\0'};
|
||||
static const WCHAR sz34[] = {'3','4','\0'};
|
||||
static const WCHAR sz1234[] = {'1','2','3','4','\0'};
|
||||
static const WCHAR date_sz12[] = {'9','/','3','0','/','1','9','8','0','1','2','\0'};
|
||||
static const WCHAR sz12_date[] = {'1','2','9','/','3','0','/','1','9','8','0','\0'};
|
||||
static const WCHAR sz_empty[] = {'\0'};
|
||||
static const WCHAR sz12_true[] = {'1','2','T','r','u','e','\0'};
|
||||
static const WCHAR sz12_false[] = {'1','2','F','a','l','s','e','\0'};
|
||||
TCHAR orig_date_format[128];
|
||||
VARTYPE leftvt, rightvt, resultvt;
|
||||
HRESULT hres;
|
||||
|
||||
/* Set date format for testing */
|
||||
lcid = LOCALE_USER_DEFAULT;
|
||||
GetLocaleInfo(lcid,LOCALE_SSHORTDATE,orig_date_format,128);
|
||||
SetLocaleInfo(lcid,LOCALE_SSHORTDATE,"M/d/yyyy");
|
||||
|
||||
VariantInit(&left);
|
||||
VariantInit(&right);
|
||||
VariantInit(&result);
|
||||
VariantInit(&expected);
|
||||
|
||||
/* Check expected types for all combinations */
|
||||
for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
|
||||
{
|
||||
|
||||
SKIPTESTS(leftvt);
|
||||
|
||||
for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
|
||||
{
|
||||
BOOL bFail = FALSE;
|
||||
SKIPTESTS(rightvt);
|
||||
|
||||
if (leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
|
||||
leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN ||
|
||||
leftvt == VT_RECORD || rightvt == VT_RECORD ||
|
||||
leftvt == VT_CLSID || rightvt == VT_CLSID ||
|
||||
leftvt == VT_BSTR_BLOB || rightvt == VT_BSTR_BLOB
|
||||
)
|
||||
continue;
|
||||
|
||||
if (leftvt == VT_ERROR || rightvt == VT_ERROR)
|
||||
resultvt = VT_EMPTY;
|
||||
else if (leftvt == VT_NULL && rightvt == VT_NULL)
|
||||
resultvt = VT_NULL;
|
||||
else if ((leftvt == VT_I2 || leftvt == VT_I4 ||
|
||||
leftvt == VT_R4 || leftvt == VT_R8 ||
|
||||
leftvt == VT_CY || leftvt == VT_BOOL ||
|
||||
leftvt == VT_BSTR || leftvt == VT_I1 ||
|
||||
leftvt == VT_UI1 || leftvt == VT_UI2 ||
|
||||
leftvt == VT_UI4 || leftvt == VT_I8 ||
|
||||
leftvt == VT_UI8 || leftvt == VT_INT ||
|
||||
leftvt == VT_UINT || leftvt == VT_EMPTY ||
|
||||
leftvt == VT_NULL || leftvt == VT_DECIMAL ||
|
||||
leftvt == VT_DATE)
|
||||
&&
|
||||
(rightvt == VT_I2 || rightvt == VT_I4 ||
|
||||
rightvt == VT_R4 || rightvt == VT_R8 ||
|
||||
rightvt == VT_CY || rightvt == VT_BOOL ||
|
||||
rightvt == VT_BSTR || rightvt == VT_I1 ||
|
||||
rightvt == VT_UI1 || rightvt == VT_UI2 ||
|
||||
rightvt == VT_UI4 || rightvt == VT_I8 ||
|
||||
rightvt == VT_UI8 || rightvt == VT_INT ||
|
||||
rightvt == VT_UINT || rightvt == VT_EMPTY ||
|
||||
rightvt == VT_NULL || rightvt == VT_DECIMAL ||
|
||||
rightvt == VT_DATE))
|
||||
{
|
||||
resultvt = VT_BSTR;
|
||||
}
|
||||
else
|
||||
resultvt = VT_EMPTY;
|
||||
|
||||
if (leftvt == VT_ERROR || rightvt == VT_ERROR)
|
||||
{
|
||||
bFail = TRUE;
|
||||
}
|
||||
|
||||
V_VT(&left) = leftvt;
|
||||
V_VT(&right) = rightvt;
|
||||
|
||||
if (leftvt == VT_BSTR)
|
||||
V_BSTR(&left) = SysAllocString(sz_empty);
|
||||
if (rightvt == VT_BSTR)
|
||||
V_BSTR(&right) = SysAllocString(sz_empty);
|
||||
if (leftvt == VT_DATE)
|
||||
V_DATE(&left) = 0.0;
|
||||
if (rightvt == VT_DATE)
|
||||
V_DATE(&right) = 0.0;
|
||||
if (leftvt == VT_DECIMAL)
|
||||
VarDecFromR8(0.0, &V_DECIMAL(&left));
|
||||
if (rightvt == VT_DECIMAL)
|
||||
VarDecFromR8(0.0, &V_DECIMAL(&right));
|
||||
|
||||
hres = VarCat(&left, &right, &result);
|
||||
if (bFail) {
|
||||
/* Determine the error code for the vt combination */
|
||||
HRESULT expected_error_num = S_OK;
|
||||
if (rightvt == VT_ERROR && leftvt <= VT_VOID)
|
||||
expected_error_num = DISP_E_TYPEMISMATCH;
|
||||
else if (leftvt == VT_ERROR && (rightvt == VT_DATE ||
|
||||
rightvt == VT_ERROR || rightvt == VT_DECIMAL))
|
||||
expected_error_num = DISP_E_TYPEMISMATCH;
|
||||
else if (rightvt == VT_DATE || rightvt == VT_ERROR ||
|
||||
rightvt == VT_DECIMAL)
|
||||
expected_error_num = DISP_E_BADVARTYPE;
|
||||
else if (leftvt == VT_ERROR || rightvt == VT_ERROR)
|
||||
expected_error_num = DISP_E_TYPEMISMATCH;
|
||||
|
||||
ok(hres == DISP_E_BADVARTYPE || hres == E_INVALIDARG ||
|
||||
hres == DISP_E_TYPEMISMATCH,
|
||||
"VarCat: %d, %d: Expected failure 0x%lX, got 0x%lX\n",
|
||||
leftvt, rightvt, expected_error_num, hres);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(V_VT(&result) == resultvt,
|
||||
"VarCat: %d, %d: expected vt %d, got vt %d\n",
|
||||
leftvt, rightvt, resultvt, V_VT(&result));
|
||||
if (hres != S_OK)
|
||||
{
|
||||
HRESULT expected_error_num;
|
||||
if (leftvt == VT_VARIANT && rightvt == VT_ERROR)
|
||||
expected_error_num = DISP_E_BADVARTYPE;
|
||||
else if (leftvt == VT_VARIANT)
|
||||
expected_error_num = DISP_E_TYPEMISMATCH;
|
||||
else if (rightvt == VT_VARIANT && (leftvt == VT_EMPTY ||
|
||||
leftvt == VT_NULL || leftvt == VT_I2 ||
|
||||
leftvt == VT_I4 || leftvt == VT_R4 ||
|
||||
leftvt == VT_R8 || leftvt == VT_CY ||
|
||||
leftvt == VT_DATE || leftvt == VT_BSTR ||
|
||||
leftvt == VT_BOOL || leftvt == VT_DECIMAL ||
|
||||
leftvt == VT_I1 || leftvt == VT_UI1 ||
|
||||
leftvt == VT_UI2 || leftvt == VT_UI4 ||
|
||||
leftvt == VT_I8 || leftvt == VT_UI8 ||
|
||||
leftvt == VT_INT || leftvt == VT_UINT
|
||||
))
|
||||
expected_error_num = DISP_E_TYPEMISMATCH;
|
||||
else
|
||||
expected_error_num = DISP_E_BADVARTYPE;
|
||||
|
||||
ok(hres == expected_error_num,
|
||||
"VarCat: %d, %d: Expected failure 0x%lX, got 0x%lX\n",
|
||||
leftvt, rightvt, expected_error_num, hres);
|
||||
}
|
||||
}
|
||||
|
||||
VariantClear(&left);
|
||||
VariantClear(&right);
|
||||
VariantClear(&result);
|
||||
}
|
||||
}
|
||||
|
||||
/* Runnning single comparison tests to compare outputs */
|
||||
|
||||
/* Test concat strings */
|
||||
V_VT(&left) = VT_BSTR;
|
||||
V_VT(&right) = VT_BSTR;
|
||||
V_VT(&expected) = VT_BSTR;
|
||||
V_BSTR(&left) = SysAllocString(sz12);
|
||||
V_BSTR(&right) = SysAllocString(sz34);
|
||||
V_BSTR(&expected) = SysAllocString(sz1234);
|
||||
VarCat(&left,&right,&result);
|
||||
ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
|
||||
"VarCat: VT_BSTR concat with VT_BSTR failed to return correct result\n");
|
||||
|
||||
VariantClear(&left);
|
||||
VariantClear(&right);
|
||||
VariantClear(&result);
|
||||
|
||||
/* Test if expression is VT_ERROR */
|
||||
V_VT(&left) = VT_ERROR;
|
||||
V_VT(&right) = VT_BSTR;
|
||||
VarCat(&left,&right,&result);
|
||||
ok(V_VT(&result) == VT_EMPTY,
|
||||
"VarCat: VT_ERROR concat with VT_BSTR should have returned VT_EMPTY\n");
|
||||
|
||||
VariantClear(&left);
|
||||
VariantClear(&right);
|
||||
VariantClear(&result);
|
||||
|
||||
V_VT(&left) = VT_BSTR;
|
||||
V_VT(&right) = VT_ERROR;
|
||||
VarCat(&left,&right,&result);
|
||||
ok(V_VT(&result) == VT_EMPTY,
|
||||
"VarCat: VT_BSTR concat with VT_ERROR should have returned VT_EMPTY\n");
|
||||
|
||||
VariantClear(&left);
|
||||
VariantClear(&right);
|
||||
VariantClear(&result);
|
||||
VariantClear(&expected);
|
||||
|
||||
/* Test combining boolean with number */
|
||||
V_VT(&left) = VT_INT;
|
||||
V_VT(&right) = VT_BOOL;
|
||||
V_VT(&expected) = VT_BSTR;
|
||||
V_INT(&left) = 12;
|
||||
V_BOOL(&right) = TRUE;
|
||||
V_BSTR(&expected) = SysAllocString(sz12_true);
|
||||
VarCat(&left,&right,&result);
|
||||
ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
|
||||
"VarCat: VT_INT concat with VT_BOOL (TRUE) returned inncorrect result\n");
|
||||
|
||||
VariantClear(&left);
|
||||
VariantClear(&right);
|
||||
VariantClear(&result);
|
||||
VariantClear(&expected);
|
||||
|
||||
V_VT(&left) = VT_INT;
|
||||
V_VT(&right) = VT_BOOL;
|
||||
V_VT(&expected) = VT_BSTR;
|
||||
V_INT(&left) = 12;
|
||||
V_BOOL(&right) = FALSE;
|
||||
V_BSTR(&expected) = SysAllocString(sz12_false);
|
||||
VarCat(&left,&right,&result);
|
||||
ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
|
||||
"VarCat: VT_INT concat with VT_BOOL (FALSE) returned inncorrect result\n");
|
||||
|
||||
VariantClear(&left);
|
||||
VariantClear(&right);
|
||||
VariantClear(&result);
|
||||
VariantClear(&expected);
|
||||
|
||||
/* Test when both expressions are numeric */
|
||||
V_VT(&left) = VT_INT;
|
||||
V_VT(&right) = VT_INT;
|
||||
V_VT(&expected) = VT_BSTR;
|
||||
V_INT(&left) = 12;
|
||||
V_INT(&right) = 34;
|
||||
V_BSTR(&expected) = SysAllocString(sz1234);
|
||||
VarCat(&left,&right,&result);
|
||||
ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
|
||||
"VarCat: NUMBER concat with NUMBER returned inncorrect result\n");
|
||||
|
||||
VariantClear(&left);
|
||||
VariantClear(&right);
|
||||
VariantClear(&result);
|
||||
|
||||
/* Test if one expression is numeric and the other is a string */
|
||||
V_VT(&left) = VT_INT;
|
||||
V_VT(&right) = VT_BSTR;
|
||||
V_INT(&left) = 12;
|
||||
V_BSTR(&right) = SysAllocString(sz34);
|
||||
VarCat(&left,&right,&result);
|
||||
ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
|
||||
"VarCat: NUMBER concat with VT_BSTR, inncorrect result\n");
|
||||
|
||||
VariantClear(&left);
|
||||
VariantClear(&right);
|
||||
VariantClear(&result);
|
||||
|
||||
V_VT(&left) = VT_BSTR;
|
||||
V_VT(&right) = VT_INT;
|
||||
V_BSTR(&left) = SysAllocString(sz12);
|
||||
V_INT(&right) = 34;
|
||||
VarCat(&left,&right,&result);
|
||||
ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
|
||||
"VarCat: VT_BSTR concat with NUMBER, inncorrect result\n");
|
||||
|
||||
VariantClear(&left);
|
||||
VariantClear(&right);
|
||||
VariantClear(&result);
|
||||
|
||||
/* Test concat dates with strings */
|
||||
V_VT(&left) = VT_BSTR;
|
||||
V_VT(&right) = VT_DATE;
|
||||
V_VT(&expected) = VT_BSTR;
|
||||
V_BSTR(&left) = SysAllocString(sz12);
|
||||
V_DATE(&right) = 29494.0;
|
||||
V_BSTR(&expected)= SysAllocString(sz12_date);
|
||||
VarCat(&left,&right,&result);
|
||||
ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
|
||||
"VarCat: VT_BSTR concat with VT_DATE returned inncorrect result\n");
|
||||
|
||||
VariantClear(&left);
|
||||
VariantClear(&right);
|
||||
VariantClear(&result);
|
||||
VariantClear(&expected);
|
||||
|
||||
V_VT(&left) = VT_DATE;
|
||||
V_VT(&right) = VT_BSTR;
|
||||
V_VT(&expected) = VT_BSTR;
|
||||
V_DATE(&left) = 29494.0;
|
||||
V_BSTR(&right) = SysAllocString(sz12);
|
||||
V_BSTR(&expected)= SysAllocString(date_sz12);
|
||||
VarCat(&left,&right,&result);
|
||||
ok(VarCmp(&result,&expected,lcid,0) == VARCMP_EQ,
|
||||
"VarCat: VT_DATE concat with VT_BSTR returned inncorrect result\n");
|
||||
|
||||
VariantClear(&left);
|
||||
VariantClear(&right);
|
||||
VariantClear(&result);
|
||||
VariantClear(&expected);
|
||||
|
||||
/* Test of both expressions are empty */
|
||||
V_VT(&left) = VT_BSTR;
|
||||
V_VT(&right) = VT_BSTR;
|
||||
V_VT(&expected) = VT_BSTR;
|
||||
V_BSTR(&left) = SysAllocString(sz_empty);
|
||||
V_BSTR(&right) = SysAllocString(sz_empty);
|
||||
V_BSTR(&expected)= SysAllocString(sz_empty);
|
||||
VarCat(&left,&right,&result);
|
||||
ok(VarCmp(&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(&left);
|
||||
VariantClear(&right);
|
||||
VariantClear(&result);
|
||||
VariantClear(&expected);
|
||||
}
|
||||
|
||||
static HRESULT (WINAPI *pVarCmp)(LPVARIANT,LPVARIANT,LCID,ULONG);
|
||||
|
||||
/* ERROR from wingdi.h is interfering here */
|
||||
|
@ -5387,5 +5705,6 @@ START_TEST(vartest)
|
|||
test_VarEqv();
|
||||
test_VarMul();
|
||||
test_VarAdd();
|
||||
test_VarCat();
|
||||
test_VarCmp();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* Copyright 1998 Jean-Claude Cote
|
||||
* Copyright 2003 Jon Griffiths
|
||||
* Copyright 2005 Daniel Remenak
|
||||
* Copyright 2006 Google (Benjamin Arai)
|
||||
*
|
||||
* The alorithm for conversion from Julian days to day/month/year is based on
|
||||
* that devised by Henry Fliegel, as implemented in PostgreSQL, which is
|
||||
|
@ -2443,53 +2444,142 @@ VarNumFromParseNum_DecOverflow:
|
|||
*/
|
||||
HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out)
|
||||
{
|
||||
VARTYPE leftvt,rightvt;
|
||||
HRESULT hres;
|
||||
static const WCHAR str_true[] = {'T','r','u','e','\0'};
|
||||
static const WCHAR str_false[] = {'F','a','l','s','e','\0'};
|
||||
leftvt = V_VT(left);
|
||||
rightvt = V_VT(right);
|
||||
|
||||
TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
|
||||
debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), out);
|
||||
|
||||
/* Should we VariantClear out? */
|
||||
/* Can we handle array, vector, by ref etc. */
|
||||
if ((V_VT(left)&VT_TYPEMASK) == VT_NULL &&
|
||||
(V_VT(right)&VT_TYPEMASK) == VT_NULL)
|
||||
/* Null and Null simply return Null */
|
||||
if (leftvt == VT_NULL && rightvt == VT_NULL)
|
||||
{
|
||||
V_VT(out) = VT_NULL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (V_VT(left) == VT_BSTR && V_VT(right) == VT_BSTR)
|
||||
/* VT_ERROR with any other value should return VT_NULL */
|
||||
else if (V_VT(left) == VT_ERROR || V_VT(right) == VT_ERROR)
|
||||
{
|
||||
V_VT(out) = VT_BSTR;
|
||||
VarBstrCat (V_BSTR(left), V_BSTR(right), &V_BSTR(out));
|
||||
return S_OK;
|
||||
V_VT(out) = VT_EMPTY;
|
||||
return DISP_E_BADVARTYPE;
|
||||
}
|
||||
if (V_VT(left) == VT_BSTR) {
|
||||
VARIANT bstrvar;
|
||||
HRESULT hres;
|
||||
|
||||
/* Concat all type that match conformance test */
|
||||
if ((leftvt == VT_I2 || leftvt == VT_I4 ||
|
||||
leftvt == VT_R4 || leftvt == VT_R8 ||
|
||||
leftvt == VT_CY || leftvt == VT_BOOL ||
|
||||
leftvt == VT_BSTR || leftvt == VT_I1 ||
|
||||
leftvt == VT_UI1 || leftvt == VT_UI2 ||
|
||||
leftvt == VT_UI4 || leftvt == VT_I8 ||
|
||||
leftvt == VT_UI8 || leftvt == VT_INT ||
|
||||
leftvt == VT_UINT || leftvt == VT_EMPTY ||
|
||||
leftvt == VT_NULL || leftvt == VT_DATE ||
|
||||
leftvt == VT_DECIMAL)
|
||||
&&
|
||||
(rightvt == VT_I2 || rightvt == VT_I4 ||
|
||||
rightvt == VT_R4 || rightvt == VT_R8 ||
|
||||
rightvt == VT_CY || rightvt == VT_BOOL ||
|
||||
rightvt == VT_BSTR || rightvt == VT_I1 ||
|
||||
rightvt == VT_UI1 || rightvt == VT_UI2 ||
|
||||
rightvt == VT_UI4 || rightvt == VT_I8 ||
|
||||
rightvt == VT_UI8 || rightvt == VT_INT ||
|
||||
rightvt == VT_UINT || rightvt == VT_EMPTY ||
|
||||
rightvt == VT_NULL || rightvt == VT_DATE ||
|
||||
rightvt == VT_DECIMAL))
|
||||
{
|
||||
VARIANT bstrvar_left, bstrvar_right;
|
||||
V_VT(out) = VT_BSTR;
|
||||
VariantInit(&bstrvar);
|
||||
hres = VariantChangeTypeEx(&bstrvar,right,0,0,VT_BSTR);
|
||||
if (hres) {
|
||||
FIXME("Failed to convert right side from vt %d to VT_BSTR?\n",V_VT(right));
|
||||
return hres;
|
||||
}
|
||||
VarBstrCat (V_BSTR(left), V_BSTR(&bstrvar), &V_BSTR(out));
|
||||
return S_OK;
|
||||
}
|
||||
if (V_VT(right) == VT_BSTR) {
|
||||
VARIANT bstrvar;
|
||||
HRESULT hres;
|
||||
|
||||
V_VT(out) = VT_BSTR;
|
||||
VariantInit(&bstrvar);
|
||||
hres = VariantChangeTypeEx(&bstrvar,left,0,0,VT_BSTR);
|
||||
if (hres) {
|
||||
FIXME("Failed to convert right side from vt %d to VT_BSTR?\n",V_VT(right));
|
||||
return hres;
|
||||
/* Convert left side variant to string */
|
||||
if (leftvt != VT_BSTR)
|
||||
{
|
||||
VariantInit(&bstrvar_left);
|
||||
if (leftvt == VT_BOOL)
|
||||
{
|
||||
/* Bools are handled as True/False strings instead of 0/-1 as in MSDN */
|
||||
V_VT(&bstrvar_left) = VT_BSTR;
|
||||
if (V_BOOL(left) == TRUE)
|
||||
V_BSTR(&bstrvar_left) = SysAllocString(str_true);
|
||||
else
|
||||
V_BSTR(&bstrvar_left) = SysAllocString(str_false);
|
||||
}
|
||||
else
|
||||
{
|
||||
hres = VariantChangeTypeEx(&bstrvar_left,left,0,0,VT_BSTR);
|
||||
if (hres != S_OK) {
|
||||
VariantClear(&bstrvar_left);
|
||||
VariantClear(&bstrvar_right);
|
||||
if (leftvt == VT_NULL && (rightvt == VT_EMPTY ||
|
||||
rightvt == VT_NULL || rightvt == VT_I2 ||
|
||||
rightvt == VT_I4 || rightvt == VT_R4 ||
|
||||
rightvt == VT_R8 || rightvt == VT_CY ||
|
||||
rightvt == VT_DATE || rightvt == VT_BSTR ||
|
||||
rightvt == VT_BOOL || rightvt == VT_DECIMAL ||
|
||||
rightvt == VT_I1 || rightvt == VT_UI1 ||
|
||||
rightvt == VT_UI2 || rightvt == VT_UI4 ||
|
||||
rightvt == VT_I8 || rightvt == VT_UI8 ||
|
||||
rightvt == VT_INT || rightvt == VT_UINT))
|
||||
return DISP_E_BADVARTYPE;
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
}
|
||||
VarBstrCat (V_BSTR(&bstrvar), V_BSTR(right), &V_BSTR(out));
|
||||
|
||||
/* convert right side variant to string */
|
||||
if (rightvt != VT_BSTR)
|
||||
{
|
||||
VariantInit(&bstrvar_right);
|
||||
if (rightvt == VT_BOOL)
|
||||
{
|
||||
/* Bools are handled as True/False strings instead of 0/-1 as in MSDN */
|
||||
V_VT(&bstrvar_right) = VT_BSTR;
|
||||
if (V_BOOL(right) == TRUE)
|
||||
V_BSTR(&bstrvar_right) = SysAllocString(str_true);
|
||||
else
|
||||
V_BSTR(&bstrvar_right) = SysAllocString(str_false);
|
||||
}
|
||||
else
|
||||
{
|
||||
hres = VariantChangeTypeEx(&bstrvar_right,right,0,0,VT_BSTR);
|
||||
if (hres != S_OK) {
|
||||
VariantClear(&bstrvar_left);
|
||||
VariantClear(&bstrvar_right);
|
||||
if (rightvt == VT_NULL && (leftvt == VT_EMPTY ||
|
||||
leftvt == VT_NULL || leftvt == VT_I2 ||
|
||||
leftvt == VT_I4 || leftvt == VT_R4 ||
|
||||
leftvt == VT_R8 || leftvt == VT_CY ||
|
||||
leftvt == VT_DATE || leftvt == VT_BSTR ||
|
||||
leftvt == VT_BOOL || leftvt == VT_DECIMAL ||
|
||||
leftvt == VT_I1 || leftvt == VT_UI1 ||
|
||||
leftvt == VT_UI2 || leftvt == VT_UI4 ||
|
||||
leftvt == VT_I8 || leftvt == VT_UI8 ||
|
||||
leftvt == VT_INT || leftvt == VT_UINT))
|
||||
return DISP_E_BADVARTYPE;
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Concat the resulting strings together */
|
||||
if (leftvt == VT_BSTR && rightvt == VT_BSTR)
|
||||
VarBstrCat (V_BSTR(left), V_BSTR(right), &V_BSTR(out));
|
||||
else if (leftvt != VT_BSTR && rightvt != VT_BSTR)
|
||||
VarBstrCat (V_BSTR(&bstrvar_left), V_BSTR(&bstrvar_right), &V_BSTR(out));
|
||||
else if (leftvt != VT_BSTR && rightvt == VT_BSTR)
|
||||
VarBstrCat (V_BSTR(&bstrvar_left), V_BSTR(right), &V_BSTR(out));
|
||||
else if (leftvt == VT_BSTR && rightvt != VT_BSTR)
|
||||
VarBstrCat (V_BSTR(left), V_BSTR(&bstrvar_right), &V_BSTR(out));
|
||||
|
||||
VariantClear(&bstrvar_left);
|
||||
VariantClear(&bstrvar_right);
|
||||
return S_OK;
|
||||
}
|
||||
FIXME ("types %d / %d not supported\n",V_VT(left)&VT_TYPEMASK, V_VT(right)&VT_TYPEMASK);
|
||||
|
||||
V_VT(out) = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue