ReactOS 0.4.17-dev-573-g8315b8c
variant.c File Reference
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "variant.h"
#include "resource.h"
#include "wine/debug.h"
Include dependency graph for variant.c:

Go to the source code of this file.

Classes

struct  tagVARIANT_NUMBER_CHARS
 

Macros

#define COBJMACROS
 
#define IsLeapYear(y)   (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))
 
#define DOS_YEAR(x)   (1980 + (x >> 9))
 
#define DOS_MONTH(x)   ((x >> 5) & 0xf)
 
#define DOS_DAY(x)   (x & 0x1f)
 
#define DOS_HOUR(x)   (x >> 11)
 
#define DOS_MINUTE(x)   ((x >> 5) & 0x3f)
 
#define DOS_SECOND(x)   ((x & 0x1f) << 1)
 
#define DOS_DATE(d, m, y)   (d | (m << 5) | ((y-1980) << 9))
 
#define DOS_TIME(h, m, s)   ((s >> 1) | (m << 5) | (h << 11))
 
#define GET_NUMBER_TEXT(fld, name)
 
#define B_PROCESSING_EXPONENT   0x1
 
#define B_NEGATIVE_EXPONENT   0x2
 
#define B_EXPONENT_START   0x4
 
#define B_INEXACT_ZEROS   0x8
 
#define B_LEADING_ZERO   0x10
 
#define B_PROCESSING_HEX   0x20
 
#define B_PROCESSING_OCT   0x40
 
#define INTEGER_VTBITS   (VTBIT_I1|VTBIT_UI1|VTBIT_I2|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|VTBIT_I8|VTBIT_UI8)
 
#define REAL_VTBITS   (VTBIT_R4|VTBIT_R8|VTBIT_CY)
 
#define FITS_AS_I1(x)   ((x) >> 8 == 0)
 
#define FITS_AS_I2(x)   ((x) >> 16 == 0)
 
#define FITS_AS_I4(x)   ((x) >> 32 == 0)
 
#define _VARCMP(a, b)    (((a) == (b)) ? VARCMP_EQ : (((a) < (b)) ? VARCMP_LT : VARCMP_GT))
 
#define ABS_CASE(typ, min)
 

Typedefs

typedef struct tagVARIANT_NUMBER_CHARS VARIANT_NUMBER_CHARS
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (variant)
 
static HRESULT VARIANT_Coerce (VARIANTARG *pd, LCID lcid, USHORT wFlags, VARIANTARG *ps, VARTYPE vt)
 
static HRESULT VARIANT_CoerceArray (VARIANTARG *pd, VARIANTARG *ps, VARTYPE vt)
 
static HRESULT VARIANT_FetchDispatchValue (LPVARIANT pvDispatch, LPVARIANT pValue)
 
static HRESULT VARIANT_ValidateType (VARTYPE vt)
 
void WINAPI VariantInit (VARIANTARG *pVarg)
 
HRESULT VARIANT_ClearInd (VARIANTARG *pVarg)
 
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear (VARIANTARG *pVarg)
 
static HRESULT VARIANT_CopyIRecordInfo (VARIANT *dest, const VARIANT *src)
 
HRESULT WINAPI VariantCopy (VARIANTARG *pvargDest, const VARIANTARG *pvargSrc)
 
static size_t VARIANT_DataSize (const VARIANT *pv)
 
HRESULT WINAPI VariantCopyInd (VARIANT *pvargDest, const VARIANTARG *pvargSrc)
 
HRESULT WINAPI DECLSPEC_HOTPATCH VariantChangeType (VARIANTARG *pvargDest, const VARIANTARG *pvargSrc, USHORT wFlags, VARTYPE vt)
 
HRESULT WINAPI VariantChangeTypeEx (VARIANTARG *pvargDest, const VARIANTARG *pvargSrc, LCID lcid, USHORT wFlags, VARTYPE vt)
 
static int VARIANT_JulianFromDate (int dateIn)
 
static int VARIANT_DateFromJulian (int dateIn)
 
static void VARIANT_DMYFromJulian (int jd, USHORT *year, USHORT *month, USHORT *day)
 
static double VARIANT_JulianFromDMY (USHORT year, USHORT month, USHORT day)
 
static HRESULT VARIANT_RollUdate (UDATE *lpUd)
 
INT WINAPI DosDateTimeToVariantTime (USHORT wDosDate, USHORT wDosTime, double *pDateOut)
 
INT WINAPI VariantTimeToDosDateTime (double dateIn, USHORT *pwDosDate, USHORT *pwDosTime)
 
INT WINAPI SystemTimeToVariantTime (LPSYSTEMTIME lpSt, double *pDateOut)
 
INT WINAPI VariantTimeToSystemTime (double dateIn, LPSYSTEMTIME lpSt)
 
HRESULT WINAPI VarDateFromUdateEx (UDATE *pUdateIn, LCID lcid, ULONG dwFlags, DATE *pDateOut)
 
HRESULT WINAPI VarDateFromUdate (UDATE *pUdateIn, ULONG dwFlags, DATE *pDateOut)
 
HRESULT WINAPI VarUdateFromDate (DATE dateIn, ULONG dwFlags, UDATE *lpUdate)
 
static void VARIANT_GetLocalisedNumberChars (VARIANT_NUMBER_CHARS *lpChars, LCID lcid, DWORD dwFlags)
 
static BOOL is_digit (WCHAR c)
 
HRESULT WINAPI VarParseNumFromStr (const OLECHAR *lpszStr, LCID lcid, ULONG dwFlags, NUMPARSE *pNumprs, BYTE *rgbDig)
 
HRESULT WINAPI VarNumFromParseNum (NUMPARSE *pNumprs, BYTE *rgbDig, ULONG dwVtBits, VARIANT *pVarDst)
 
HRESULT WINAPI VarCat (LPVARIANT left, LPVARIANT right, LPVARIANT out)
 
static HRESULT _VarChangeTypeExWrap (VARIANTARG *pvargDest, VARIANTARG *pvargSrc, LCID lcid, USHORT wFlags, VARTYPE vt)
 
HRESULT WINAPI VarCmp (LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
 
HRESULT WINAPI VarAnd (LPVARIANT left, LPVARIANT right, LPVARIANT result)
 
HRESULT WINAPI VarAdd (LPVARIANT left, LPVARIANT right, LPVARIANT result)
 
HRESULT WINAPI VarMul (LPVARIANT left, LPVARIANT right, LPVARIANT result)
 
HRESULT WINAPI VarDiv (LPVARIANT left, LPVARIANT right, LPVARIANT result)
 
HRESULT WINAPI VarSub (LPVARIANT left, LPVARIANT right, LPVARIANT result)
 
HRESULT WINAPI VarOr (LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
 
HRESULT WINAPI VarAbs (LPVARIANT pVarIn, LPVARIANT pVarOut)
 
HRESULT WINAPI VarFix (LPVARIANT pVarIn, LPVARIANT pVarOut)
 
HRESULT WINAPI VarInt (LPVARIANT pVarIn, LPVARIANT pVarOut)
 
HRESULT WINAPI VarXor (LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
 
HRESULT WINAPI VarEqv (LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
 
HRESULT WINAPI VarNeg (LPVARIANT pVarIn, LPVARIANT pVarOut)
 
HRESULT WINAPI VarNot (LPVARIANT pVarIn, LPVARIANT pVarOut)
 
HRESULT WINAPI VarRound (LPVARIANT pVarIn, int deci, LPVARIANT pVarOut)
 
HRESULT WINAPI VarIdiv (LPVARIANT left, LPVARIANT right, LPVARIANT result)
 
HRESULT WINAPI VarMod (LPVARIANT left, LPVARIANT right, LPVARIANT result)
 
HRESULT WINAPI VarPow (LPVARIANT left, LPVARIANT right, LPVARIANT result)
 
HRESULT WINAPI VarImp (LPVARIANT left, LPVARIANT right, LPVARIANT result)
 

Macro Definition Documentation

◆ _VARCMP

#define _VARCMP (   a,
  b 
)     (((a) == (b)) ? VARCMP_EQ : (((a) < (b)) ? VARCMP_LT : VARCMP_GT))

◆ ABS_CASE

#define ABS_CASE (   typ,
  min 
)
Value:
case VT_##typ: if (V_##typ(pVarIn) == min) hRet = DISP_E_OVERFLOW; \
else if (V_##typ(pVarIn) < 0) V_##typ(pVarOut) = -V_##typ(pVarIn); \
break
#define min(a, b)
Definition: monoChain.cc:55
#define DISP_E_OVERFLOW
Definition: winerror.h:3622

◆ B_EXPONENT_START

#define B_EXPONENT_START   0x4

Definition at line 1537 of file variant.c.

◆ B_INEXACT_ZEROS

#define B_INEXACT_ZEROS   0x8

Definition at line 1538 of file variant.c.

◆ B_LEADING_ZERO

#define B_LEADING_ZERO   0x10

Definition at line 1539 of file variant.c.

◆ B_NEGATIVE_EXPONENT

#define B_NEGATIVE_EXPONENT   0x2

Definition at line 1536 of file variant.c.

◆ B_PROCESSING_EXPONENT

#define B_PROCESSING_EXPONENT   0x1

Definition at line 1535 of file variant.c.

◆ B_PROCESSING_HEX

#define B_PROCESSING_HEX   0x20

Definition at line 1540 of file variant.c.

◆ B_PROCESSING_OCT

#define B_PROCESSING_OCT   0x40

Definition at line 1541 of file variant.c.

◆ COBJMACROS

#define COBJMACROS

Definition at line 32 of file variant.c.

◆ DOS_DATE

#define DOS_DATE (   d,
  m,
  y 
)    (d | (m << 5) | ((y-1980) << 9))

Definition at line 1081 of file variant.c.

◆ DOS_DAY

#define DOS_DAY (   x)    (x & 0x1f)

Definition at line 1076 of file variant.c.

◆ DOS_HOUR

#define DOS_HOUR (   x)    (x >> 11)

Definition at line 1077 of file variant.c.

◆ DOS_MINUTE

#define DOS_MINUTE (   x)    ((x >> 5) & 0x3f)

Definition at line 1078 of file variant.c.

◆ DOS_MONTH

#define DOS_MONTH (   x)    ((x >> 5) & 0xf)

Definition at line 1075 of file variant.c.

◆ DOS_SECOND

#define DOS_SECOND (   x)    ((x & 0x1f) << 1)

Definition at line 1079 of file variant.c.

◆ DOS_TIME

#define DOS_TIME (   h,
  m,
  s 
)    ((s >> 1) | (m << 5) | (h << 11))

Definition at line 1082 of file variant.c.

◆ DOS_YEAR

#define DOS_YEAR (   x)    (1980 + (x >> 9))

Definition at line 1074 of file variant.c.

◆ FITS_AS_I1

#define FITS_AS_I1 (   x)    ((x) >> 8 == 0)

Definition at line 2026 of file variant.c.

◆ FITS_AS_I2

#define FITS_AS_I2 (   x)    ((x) >> 16 == 0)

Definition at line 2027 of file variant.c.

◆ FITS_AS_I4

#define FITS_AS_I4 (   x)    ((x) >> 32 == 0)

Definition at line 2028 of file variant.c.

◆ GET_NUMBER_TEXT

#define GET_NUMBER_TEXT (   fld,
  name 
)
Value:
buff[0] = 0; \
if (!GetLocaleInfoW(lcid, lctype|fld, buff, ARRAY_SIZE(buff))) \
WARN("buffer too small for " #fld "\n"); \
else \
if (buff[0]) lpChars->name = buff[0]; \
TRACE("lcid 0x%lx, " #name "=%s\n", lcid, wine_dbgstr_wn(&lpChars->name, 1))
#define ARRAY_SIZE(A)
Definition: main.h:20
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: locale.c:1675
LCID lcid
Definition: locale.c:5660
#define wine_dbgstr_wn
Definition: testlist.c:2
static const char *static const char const char DWORD void DWORD *static const char const char DWORD void DWORD *static const char DWORD DWORD void * buff
Definition: shcore.c:41
Definition: name.c:39

Definition at line 1499 of file variant.c.

◆ INTEGER_VTBITS

Definition at line 2021 of file variant.c.

◆ IsLeapYear

#define IsLeapYear (   y)    (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))

Definition at line 1025 of file variant.c.

◆ REAL_VTBITS

#define REAL_VTBITS   (VTBIT_R4|VTBIT_R8|VTBIT_CY)

Definition at line 2023 of file variant.c.

Typedef Documentation

◆ VARIANT_NUMBER_CHARS

Function Documentation

◆ _VarChangeTypeExWrap()

static HRESULT _VarChangeTypeExWrap ( VARIANTARG pvargDest,
VARIANTARG pvargSrc,
LCID  lcid,
USHORT  wFlags,
VARTYPE  vt 
)
static

Definition at line 2724 of file variant.c.

2726{
2727 VARIANTARG vtmpsrc = *pvargSrc;
2728
2729 V_VT(&vtmpsrc) &= ~VT_RESERVED;
2730 return VariantChangeTypeEx(pvargDest,&vtmpsrc,lcid,wFlags,vt);
2731}
static REFPROPVARIANT PROPVAR_CHANGE_FLAGS VARTYPE vt
Definition: suminfo.c:91
#define V_VT(A)
Definition: oleauto.h:211
HRESULT WINAPI VariantChangeTypeEx(VARIANTARG *pvargDest, const VARIANTARG *pvargSrc, LCID lcid, USHORT wFlags, VARTYPE vt)
Definition: variant.c:965
WINBASEAPI _In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon_undoc.h:337

Referenced by VarCmp().

◆ DosDateTimeToVariantTime()

INT WINAPI DosDateTimeToVariantTime ( USHORT  wDosDate,
USHORT  wDosTime,
double pDateOut 
)

Definition at line 1188 of file variant.c.

1190{
1191 UDATE ud;
1192
1193 TRACE("(0x%x(%d/%d/%d),0x%x(%d:%d:%d),%p)\n",
1194 wDosDate, DOS_YEAR(wDosDate), DOS_MONTH(wDosDate), DOS_DAY(wDosDate),
1195 wDosTime, DOS_HOUR(wDosTime), DOS_MINUTE(wDosTime), DOS_SECOND(wDosTime),
1196 pDateOut);
1197
1198 ud.st.wYear = DOS_YEAR(wDosDate);
1199 ud.st.wMonth = DOS_MONTH(wDosDate);
1200 if (ud.st.wYear > 2099 || ud.st.wMonth > 12)
1201 return FALSE;
1202 ud.st.wDay = DOS_DAY(wDosDate);
1203 ud.st.wHour = DOS_HOUR(wDosTime);
1204 ud.st.wMinute = DOS_MINUTE(wDosTime);
1205 ud.st.wSecond = DOS_SECOND(wDosTime);
1206 ud.st.wDayOfWeek = ud.st.wMilliseconds = 0;
1207 if (ud.st.wHour > 23 || ud.st.wMinute > 59 || ud.st.wSecond > 59)
1208 return FALSE; /* Invalid values in Dos*/
1209
1210 return VarDateFromUdate(&ud, 0, pDateOut) == S_OK;
1211}
#define FALSE
Definition: types.h:117
#define S_OK
Definition: intsafe.h:52
#define TRACE(s)
Definition: solgame.cpp:4
Definition: oleauto.h:720
SYSTEMTIME st
Definition: oleauto.h:721
WORD wMilliseconds
Definition: minwinbase.h:263
WORD wSecond
Definition: minwinbase.h:262
WORD wMinute
Definition: minwinbase.h:261
WORD wDayOfWeek
Definition: minwinbase.h:258
#define DOS_MONTH(x)
Definition: variant.c:1075
#define DOS_DAY(x)
Definition: variant.c:1076
#define DOS_SECOND(x)
Definition: variant.c:1079
#define DOS_MINUTE(x)
Definition: variant.c:1078
#define DOS_YEAR(x)
Definition: variant.c:1074
#define DOS_HOUR(x)
Definition: variant.c:1077
HRESULT WINAPI VarDateFromUdate(UDATE *pUdateIn, ULONG dwFlags, DATE *pDateOut)
Definition: variant.c:1383

Referenced by CFolderItem::get_ModifyDate(), CZipFolder::GetDetailsEx(), CFSFolder::GetDetailsEx(), CCabFolder::GetItemDetails(), and test_dos2dt().

◆ is_digit()

static BOOL is_digit ( WCHAR  c)
inlinestatic

Definition at line 1543 of file variant.c.

1544{
1545 return '0' <= c && c <= '9';
1546}
const GLubyte * c
Definition: glext.h:8905

◆ SystemTimeToVariantTime()

INT WINAPI SystemTimeToVariantTime ( LPSYSTEMTIME  lpSt,
double pDateOut 
)

Definition at line 1263 of file variant.c.

1264{
1265 UDATE ud;
1266
1267 TRACE("(%p->%d/%d/%d %d:%d:%d,%p)\n", lpSt, lpSt->wDay, lpSt->wMonth,
1268 lpSt->wYear, lpSt->wHour, lpSt->wMinute, lpSt->wSecond, pDateOut);
1269
1270 if (lpSt->wMonth > 12)
1271 return FALSE;
1272 if (lpSt->wDay > 31)
1273 return FALSE;
1274 if ((short)lpSt->wYear < 0)
1275 return FALSE;
1276
1277 ud.st = *lpSt;
1278 return VarDateFromUdate(&ud, 0, pDateOut) == S_OK;
1279}

Referenced by get_date_from_filetime(), Global_Now(), InitVariantFromFileTime(), summaryinfo_invoke(), test_InitVariantFromFileTime(), test_st2dt(), test_SummaryInfo(), VarDateFromStr(), and variant_from_dt().

◆ VarAbs()

HRESULT WINAPI VarAbs ( LPVARIANT  pVarIn,
LPVARIANT  pVarOut 
)

Definition at line 4327 of file variant.c.

4328{
4329 HRESULT hRet = S_OK;
4330 VARIANT temp;
4331
4332 VariantInit(&temp);
4333
4334 TRACE("(%s,%p)\n", debugstr_variant(pVarIn), pVarOut);
4335
4336 /* Handle VT_DISPATCH by storing and taking address of returned value */
4337 if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
4338 {
4339 hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
4340 if (FAILED(hRet)) goto VarAbs_Exit;
4341 pVarIn = &temp;
4342 }
4343
4344 if (V_ISARRAY(pVarIn) || V_VT(pVarIn) == VT_UNKNOWN ||
4345 V_VT(pVarIn) == VT_DISPATCH || V_VT(pVarIn) == VT_RECORD ||
4346 V_VT(pVarIn) == VT_ERROR)
4347 {
4348 hRet = DISP_E_TYPEMISMATCH;
4349 goto VarAbs_Exit;
4350 }
4351 *pVarOut = *pVarIn; /* Shallow copy the value, and invert it if needed */
4352
4353#define ABS_CASE(typ,min) \
4354 case VT_##typ: if (V_##typ(pVarIn) == min) hRet = DISP_E_OVERFLOW; \
4355 else if (V_##typ(pVarIn) < 0) V_##typ(pVarOut) = -V_##typ(pVarIn); \
4356 break
4357
4358 switch (V_VT(pVarIn))
4359 {
4360 ABS_CASE(I1,I1_MIN);
4361 case VT_BOOL:
4362 V_VT(pVarOut) = VT_I2;
4363 /* BOOL->I2, Fall through ... */
4364 ABS_CASE(I2,I2_MIN);
4365 case VT_INT:
4366 ABS_CASE(I4,I4_MIN);
4367 ABS_CASE(I8,I8_MIN);
4368 case VT_R4:
4369 if (V_R4(pVarOut) < 0.0) V_R4(pVarOut) = -V_R4(pVarOut);
4370 break;
4371 case VT_BSTR:
4372 hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(pVarOut));
4373 if (FAILED(hRet))
4374 break;
4375 V_VT(pVarOut) = VT_R8;
4376 /* Fall through ... */
4377 case VT_DATE:
4378 case VT_R8:
4379 if (V_R8(pVarOut) < 0.0) V_R8(pVarOut) = -V_R8(pVarOut);
4380 break;
4381 case VT_CY:
4382 hRet = VarCyAbs(V_CY(pVarIn), & V_CY(pVarOut));
4383 break;
4384 case VT_DECIMAL:
4385 V_DECIMAL(pVarOut).sign &= ~DECIMAL_NEG;
4386 break;
4387 case VT_UI1:
4388 case VT_UI2:
4389 case VT_UINT:
4390 case VT_UI4:
4391 case VT_UI8:
4392 /* No-Op */
4393 break;
4394 case VT_EMPTY:
4395 V_VT(pVarOut) = VT_I2;
4396 case VT_NULL:
4397 V_I2(pVarOut) = 0;
4398 break;
4399 default:
4400 hRet = DISP_E_BADVARTYPE;
4401 }
4402
4403VarAbs_Exit:
4405 return hRet;
4406}
@ VT_UI8
Definition: compat.h:2315
@ VT_BSTR
Definition: compat.h:2303
@ VT_INT
Definition: compat.h:2316
@ VT_R4
Definition: compat.h:2299
@ VT_NULL
Definition: compat.h:2296
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_TYPEMASK
Definition: compat.h:2346
@ VT_UI2
Definition: compat.h:2312
@ VT_DECIMAL
Definition: compat.h:2309
@ VT_ERROR
Definition: compat.h:2305
@ VT_R8
Definition: compat.h:2300
@ VT_CY
Definition: compat.h:2301
@ VT_DATE
Definition: compat.h:2302
@ VT_BOOL
Definition: compat.h:2306
@ VT_I2
Definition: compat.h:2297
@ VT_UI4
Definition: compat.h:2313
@ VT_UINT
Definition: compat.h:2317
@ VT_EMPTY
Definition: compat.h:2295
@ VT_RECORD
Definition: compat.h:2326
@ VT_DISPATCH
Definition: compat.h:2304
@ VT_UI1
Definition: compat.h:2311
HRESULT WINAPI VarCyAbs(CY cyIn, CY *pCyOut)
Definition: vartype.c:3870
HRESULT WINAPI VarR8FromStr(const OLECHAR *strIn, LCID lcid, ULONG dwFlags, double *pDblOut)
Definition: vartype.c:3145
static const char * debugstr_variant(const VARIANT *var)
Definition: dom.c:505
#define FAILED(hr)
Definition: intsafe.h:51
#define LOCALE_USER_DEFAULT
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_ISARRAY(A)
Definition: oleauto.h:218
#define V_R4(A)
Definition: oleauto.h:260
#define V_DECIMAL(A)
Definition: oleauto.h:236
#define V_CY(A)
Definition: oleauto.h:229
#define V_R8(A)
Definition: oleauto.h:262
#define V_I2(A)
Definition: oleauto.h:245
static calc_node_t temp
Definition: rpn_ieee.c:38
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:626
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:547
#define ABS_CASE(typ, min)
static HRESULT VARIANT_FetchDispatchValue(LPVARIANT pvDispatch, LPVARIANT pValue)
Definition: variant.c:504
#define I2_MIN
Definition: variant.h:56
#define I8_MIN
Definition: variant.h:64
#define I1_MIN
Definition: variant.h:52
#define I4_MIN
Definition: variant.h:60
#define DISP_E_BADVARTYPE
Definition: winerror.h:3620
#define DISP_E_TYPEMISMATCH
Definition: winerror.h:3617

Referenced by Global_Abs(), and test_VarAbs().

◆ VarAdd()

HRESULT WINAPI VarAdd ( LPVARIANT  left,
LPVARIANT  right,
LPVARIANT  result 
)

Definition at line 3194 of file variant.c.

3195{
3196 HRESULT hres;
3197 VARTYPE lvt, rvt, resvt, tvt;
3198 VARIANT lv, rv, tv;
3199 VARIANT tempLeft, tempRight;
3200 double r8res;
3201
3202 /* Variant priority for coercion. Sorted from lowest to highest.
3203 VT_ERROR shows an invalid input variant type. */
3204 enum coerceprio { vt_EMPTY, vt_UI1, vt_I2, vt_I4, vt_I8, vt_BSTR,vt_R4,
3205 vt_R8, vt_CY, vt_DATE, vt_DECIMAL, vt_DISPATCH, vt_NULL,
3206 vt_ERROR };
3207 /* Mapping from priority to variant type. Keep in sync with coerceprio! */
3208 static const VARTYPE prio2vt[] = { VT_EMPTY, VT_UI1, VT_I2, VT_I4, VT_I8, VT_BSTR, VT_R4,
3210 VT_NULL, VT_ERROR };
3211
3212 /* Mapping for coercion from input variant to priority of result variant. */
3213 static const VARTYPE coerce[] = {
3214 /* VT_EMPTY, VT_NULL, VT_I2, VT_I4, VT_R4 */
3215 vt_EMPTY, vt_NULL, vt_I2, vt_I4, vt_R4,
3216 /* VT_R8, VT_CY, VT_DATE, VT_BSTR, VT_DISPATCH */
3217 vt_R8, vt_CY, vt_DATE, vt_BSTR, vt_DISPATCH,
3218 /* VT_ERROR, VT_BOOL, VT_VARIANT, VT_UNKNOWN, VT_DECIMAL */
3219 vt_ERROR, vt_I2, vt_ERROR, vt_ERROR, vt_DECIMAL,
3220 /* 15, VT_I1, VT_UI1, VT_UI2, VT_UI4 VT_I8 */
3221 vt_ERROR, vt_ERROR, vt_UI1, vt_ERROR, vt_ERROR, vt_I8
3222 };
3223
3225
3226 VariantInit(&lv);
3227 VariantInit(&rv);
3228 VariantInit(&tv);
3229 VariantInit(&tempLeft);
3230 VariantInit(&tempRight);
3231
3232 /* Handle VT_DISPATCH by storing and taking address of returned value */
3233 if ((V_VT(left) & VT_TYPEMASK) != VT_NULL && (V_VT(right) & VT_TYPEMASK) != VT_NULL)
3234 {
3235 if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
3236 {
3237 hres = VARIANT_FetchDispatchValue(left, &tempLeft);
3238 if (FAILED(hres)) goto end;
3239 left = &tempLeft;
3240 }
3241 if ((V_VT(right) & VT_TYPEMASK) == VT_DISPATCH)
3242 {
3243 hres = VARIANT_FetchDispatchValue(right, &tempRight);
3244 if (FAILED(hres)) goto end;
3245 right = &tempRight;
3246 }
3247 }
3248
3249 lvt = V_VT(left)&VT_TYPEMASK;
3250 rvt = V_VT(right)&VT_TYPEMASK;
3251
3252 /* If we have any flag set (VT_ARRAY, VT_VECTOR, etc.) bail out.
3253 Same for any input variant type > VT_I8 */
3254 if (V_VT(left) & ~VT_TYPEMASK || V_VT(right) & ~VT_TYPEMASK ||
3255 lvt > VT_I8 || rvt > VT_I8) {
3257 goto end;
3258 }
3259
3260 /* Determine the variant type to coerce to. */
3261 if (coerce[lvt] > coerce[rvt]) {
3262 resvt = prio2vt[coerce[lvt]];
3263 tvt = prio2vt[coerce[rvt]];
3264 } else {
3265 resvt = prio2vt[coerce[rvt]];
3266 tvt = prio2vt[coerce[lvt]];
3267 }
3268
3269 /* Special cases where the result variant type is defined by both
3270 input variants and not only that with the highest priority */
3271 if (resvt == VT_BSTR) {
3272 if (tvt == VT_EMPTY || tvt == VT_BSTR)
3273 resvt = VT_BSTR;
3274 else
3275 resvt = VT_R8;
3276 }
3277 if (resvt == VT_R4 && (tvt == VT_BSTR || tvt == VT_I8 || tvt == VT_I4))
3278 resvt = VT_R8;
3279
3280 /* For overflow detection use the biggest compatible type for the
3281 addition */
3282 switch (resvt) {
3283 case VT_ERROR:
3285 goto end;
3286 case VT_NULL:
3287 hres = S_OK;
3288 V_VT(result) = VT_NULL;
3289 goto end;
3290 case VT_DISPATCH:
3291 FIXME("cannot handle variant type VT_DISPATCH\n");
3293 goto end;
3294 case VT_EMPTY:
3295 resvt = VT_I2;
3296 /* Fall through */
3297 case VT_UI1:
3298 case VT_I2:
3299 case VT_I4:
3300 case VT_I8:
3301 tvt = VT_I8;
3302 break;
3303 case VT_DATE:
3304 case VT_R4:
3305 tvt = VT_R8;
3306 break;
3307 default:
3308 tvt = resvt;
3309 }
3310
3311 /* Now coerce the variants */
3312 hres = VariantChangeType(&lv, left, 0, tvt);
3313 if (FAILED(hres))
3314 goto end;
3315 hres = VariantChangeType(&rv, right, 0, tvt);
3316 if (FAILED(hres))
3317 goto end;
3318
3319 /* Do the math */
3320 hres = S_OK;
3321 V_VT(result) = resvt;
3322 switch (tvt) {
3323 case VT_DECIMAL:
3324 hres = VarDecAdd(&V_DECIMAL(&lv), &V_DECIMAL(&rv),
3325 &V_DECIMAL(result));
3326 goto end;
3327 case VT_CY:
3328 hres = VarCyAdd(V_CY(&lv), V_CY(&rv), &V_CY(result));
3329 goto end;
3330 case VT_BSTR:
3331 /* We do not add those, we concatenate them. */
3332 hres = VarBstrCat(V_BSTR(&lv), V_BSTR(&rv), &V_BSTR(result));
3333 goto end;
3334 case VT_I8:
3335 /* Overflow detection */
3336 r8res = (double)V_I8(&lv) + (double)V_I8(&rv);
3337 if (r8res > (double)I8_MAX || r8res < (double)I8_MIN) {
3338 V_VT(result) = VT_R8;
3339 V_R8(result) = r8res;
3340 goto end;
3341 } else {
3342 V_VT(&tv) = tvt;
3343 V_I8(&tv) = V_I8(&lv) + V_I8(&rv);
3344 }
3345 break;
3346 case VT_R8:
3347 V_VT(&tv) = tvt;
3348 /* FIXME: overflow detection */
3349 V_R8(&tv) = V_R8(&lv) + V_R8(&rv);
3350 break;
3351 default:
3352 ERR("We shouldn't get here! tvt = %d!\n", tvt);
3353 break;
3354 }
3355 if (resvt != tvt) {
3356 if ((hres = VariantChangeType(result, &tv, 0, resvt)) != S_OK) {
3357 /* Overflow! Change to the vartype with the next higher priority.
3358 With one exception: I4 ==> R8 even if it would fit in I8 */
3359 if (resvt == VT_I4)
3360 resvt = VT_R8;
3361 else
3362 resvt = prio2vt[coerce[resvt] + 1];
3363 hres = VariantChangeType(result, &tv, 0, resvt);
3364 }
3365 } else
3366 hres = VariantCopy(result, &tv);
3367
3368end:
3369 if (hres != S_OK) {
3370 V_VT(result) = VT_EMPTY;
3371 V_I4(result) = 0; /* No V_EMPTY */
3372 }
3373 VariantClear(&lv);
3374 VariantClear(&rv);
3375 VariantClear(&tv);
3376 VariantClear(&tempLeft);
3377 VariantClear(&tempRight);
3378 TRACE("returning %#lx, %s\n", hres, debugstr_variant(result));
3379 return hres;
3380}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
unsigned short VARTYPE
Definition: compat.h:2254
@ VT_I8
Definition: compat.h:2314
@ VT_I4
Definition: compat.h:2298
HRESULT WINAPI VarDecAdd(const DECIMAL *pDecLeft, const DECIMAL *pDecRight, DECIMAL *pDecOut)
Definition: vartype.c:4580
HRESULT WINAPI VarBstrCat(BSTR pbstrLeft, BSTR pbstrRight, BSTR *pbstrOut)
Definition: vartype.c:7168
HRESULT WINAPI VarCyAdd(CY cyLeft, CY cyRight, CY *pCyOut)
Definition: vartype.c:3779
GLuint GLuint end
Definition: gl.h:1545
GLdouble GLdouble right
Definition: glext.h:10859
GLint left
Definition: glext.h:7726
GLuint64EXT * result
Definition: glext.h:11304
HRESULT hres
Definition: protocol.c:465
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:91
#define V_I8(A)
Definition: oleauto.h:249
#define V_I4(A)
Definition: oleauto.h:247
HRESULT WINAPI VariantCopy(VARIANTARG *pvargDest, const VARIANTARG *pvargSrc)
Definition: variant.c:724
HRESULT WINAPI DECLSPEC_HOTPATCH VariantChangeType(VARIANTARG *pvargDest, const VARIANTARG *pvargSrc, USHORT wFlags, VARTYPE vt)
Definition: variant.c:939
#define I8_MAX
Definition: variant.h:63

Referenced by interp_add(), interp_incc(), and test_VarAdd().

◆ VarAnd()

HRESULT WINAPI VarAnd ( LPVARIANT  left,
LPVARIANT  right,
LPVARIANT  result 
)

Definition at line 2958 of file variant.c.

2959{
2960 HRESULT hres = S_OK;
2961 VARTYPE resvt = VT_EMPTY;
2962 VARTYPE leftvt,rightvt;
2963 VARTYPE rightExtraFlags,leftExtraFlags,ExtraFlags;
2964 VARIANT varLeft, varRight;
2965 VARIANT tempLeft, tempRight;
2966
2967 VariantInit(&varLeft);
2968 VariantInit(&varRight);
2969 VariantInit(&tempLeft);
2970 VariantInit(&tempRight);
2971
2973
2974 /* Handle VT_DISPATCH by storing and taking address of returned value */
2975 if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
2976 {
2977 hres = VARIANT_FetchDispatchValue(left, &tempLeft);
2978 if (FAILED(hres)) goto VarAnd_Exit;
2979 left = &tempLeft;
2980 }
2981 if ((V_VT(right) & VT_TYPEMASK) == VT_DISPATCH)
2982 {
2983 hres = VARIANT_FetchDispatchValue(right, &tempRight);
2984 if (FAILED(hres)) goto VarAnd_Exit;
2985 right = &tempRight;
2986 }
2987
2988 leftvt = V_VT(left)&VT_TYPEMASK;
2989 rightvt = V_VT(right)&VT_TYPEMASK;
2990 leftExtraFlags = V_VT(left)&(~VT_TYPEMASK);
2991 rightExtraFlags = V_VT(right)&(~VT_TYPEMASK);
2992
2993 if (leftExtraFlags != rightExtraFlags)
2994 {
2996 goto VarAnd_Exit;
2997 }
2998 ExtraFlags = leftExtraFlags;
2999
3000 /* Native VarAnd always returns an error when using extra
3001 * flags or if the variant combination is I8 and INT.
3002 */
3003 if ((leftvt == VT_I8 && rightvt == VT_INT) ||
3004 (leftvt == VT_INT && rightvt == VT_I8) ||
3005 ExtraFlags != 0)
3006 {
3008 goto VarAnd_Exit;
3009 }
3010
3011 /* Determine return type */
3012 else if (leftvt == VT_I8 || rightvt == VT_I8)
3013 resvt = VT_I8;
3014 else if (leftvt == VT_I4 || rightvt == VT_I4 ||
3015 leftvt == VT_UINT || rightvt == VT_UINT ||
3016 leftvt == VT_INT || rightvt == VT_INT ||
3017 leftvt == VT_R4 || rightvt == VT_R4 ||
3018 leftvt == VT_R8 || rightvt == VT_R8 ||
3019 leftvt == VT_CY || rightvt == VT_CY ||
3020 leftvt == VT_DATE || rightvt == VT_DATE ||
3021 leftvt == VT_I1 || rightvt == VT_I1 ||
3022 leftvt == VT_UI2 || rightvt == VT_UI2 ||
3023 leftvt == VT_UI4 || rightvt == VT_UI4 ||
3024 leftvt == VT_UI8 || rightvt == VT_UI8 ||
3025 leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
3026 resvt = VT_I4;
3027 else if (leftvt == VT_UI1 || rightvt == VT_UI1 ||
3028 leftvt == VT_I2 || rightvt == VT_I2 ||
3029 leftvt == VT_EMPTY || rightvt == VT_EMPTY)
3030 if ((leftvt == VT_NULL && rightvt == VT_UI1) ||
3031 (leftvt == VT_UI1 && rightvt == VT_NULL) ||
3032 (leftvt == VT_UI1 && rightvt == VT_UI1))
3033 resvt = VT_UI1;
3034 else
3035 resvt = VT_I2;
3036 else if (leftvt == VT_BOOL || rightvt == VT_BOOL ||
3037 (leftvt == VT_BSTR && rightvt == VT_BSTR))
3038 resvt = VT_BOOL;
3039 else if (leftvt == VT_NULL || rightvt == VT_NULL ||
3040 leftvt == VT_BSTR || rightvt == VT_BSTR)
3041 resvt = VT_NULL;
3042 else
3043 {
3045 goto VarAnd_Exit;
3046 }
3047
3048 if (leftvt == VT_NULL || rightvt == VT_NULL)
3049 {
3050 /*
3051 * Special cases for when left variant is VT_NULL
3052 * (VT_NULL & 0 = VT_NULL, VT_NULL & value = value)
3053 */
3054 if (leftvt == VT_NULL)
3055 {
3057 switch(rightvt)
3058 {
3059 case VT_I1: if (V_I1(right)) resvt = VT_NULL; break;
3060 case VT_UI1: if (V_UI1(right)) resvt = VT_NULL; break;
3061 case VT_I2: if (V_I2(right)) resvt = VT_NULL; break;
3062 case VT_UI2: if (V_UI2(right)) resvt = VT_NULL; break;
3063 case VT_I4: if (V_I4(right)) resvt = VT_NULL; break;
3064 case VT_UI4: if (V_UI4(right)) resvt = VT_NULL; break;
3065 case VT_I8: if (V_I8(right)) resvt = VT_NULL; break;
3066 case VT_UI8: if (V_UI8(right)) resvt = VT_NULL; break;
3067 case VT_INT: if (V_INT(right)) resvt = VT_NULL; break;
3068 case VT_UINT: if (V_UINT(right)) resvt = VT_NULL; break;
3069 case VT_BOOL: if (V_BOOL(right)) resvt = VT_NULL; break;
3070 case VT_R4: if (V_R4(right)) resvt = VT_NULL; break;
3071 case VT_R8: if (V_R8(right)) resvt = VT_NULL; break;
3072 case VT_CY:
3073 if(V_CY(right).int64)
3074 resvt = VT_NULL;
3075 break;
3076 case VT_DECIMAL:
3077 if (V_DECIMAL(right).Hi32 || V_DECIMAL(right).Lo64)
3078 resvt = VT_NULL;
3079 break;
3080 case VT_BSTR:
3083 if (FAILED(hres))
3084 return hres;
3085 else if (b)
3086 V_VT(result) = VT_NULL;
3087 else
3088 {
3089 V_VT(result) = VT_BOOL;
3090 V_BOOL(result) = b;
3091 }
3092 goto VarAnd_Exit;
3093 }
3094 }
3095 V_VT(result) = resvt;
3096 goto VarAnd_Exit;
3097 }
3098
3099 hres = VariantCopy(&varLeft, left);
3100 if (FAILED(hres)) goto VarAnd_Exit;
3101
3102 hres = VariantCopy(&varRight, right);
3103 if (FAILED(hres)) goto VarAnd_Exit;
3104
3105 if (resvt == VT_I4 && V_VT(&varLeft) == VT_UI4)
3106 V_VT(&varLeft) = VT_I4; /* Don't overflow */
3107 else
3108 {
3109 double d;
3110
3111 if (V_VT(&varLeft) == VT_BSTR &&
3112 FAILED(VarR8FromStr(V_BSTR(&varLeft),
3113 LOCALE_USER_DEFAULT, 0, &d)))
3114 hres = VariantChangeType(&varLeft,&varLeft,
3116 if (SUCCEEDED(hres) && V_VT(&varLeft) != resvt)
3117 hres = VariantChangeType(&varLeft,&varLeft,0,resvt);
3118 if (FAILED(hres)) goto VarAnd_Exit;
3119 }
3120
3121 if (resvt == VT_I4 && V_VT(&varRight) == VT_UI4)
3122 V_VT(&varRight) = VT_I4; /* Don't overflow */
3123 else
3124 {
3125 double d;
3126
3127 if (V_VT(&varRight) == VT_BSTR &&
3128 FAILED(VarR8FromStr(V_BSTR(&varRight),
3129 LOCALE_USER_DEFAULT, 0, &d)))
3130 hres = VariantChangeType(&varRight, &varRight,
3132 if (SUCCEEDED(hres) && V_VT(&varRight) != resvt)
3133 hres = VariantChangeType(&varRight, &varRight, 0, resvt);
3134 if (FAILED(hres)) goto VarAnd_Exit;
3135 }
3136
3137 V_VT(result) = resvt;
3138 switch(resvt)
3139 {
3140 case VT_I8:
3141 V_I8(result) = V_I8(&varLeft) & V_I8(&varRight);
3142 break;
3143 case VT_I4:
3144 V_I4(result) = V_I4(&varLeft) & V_I4(&varRight);
3145 break;
3146 case VT_I2:
3147 V_I2(result) = V_I2(&varLeft) & V_I2(&varRight);
3148 break;
3149 case VT_UI1:
3150 V_UI1(result) = V_UI1(&varLeft) & V_UI1(&varRight);
3151 break;
3152 case VT_BOOL:
3153 V_BOOL(result) = V_BOOL(&varLeft) & V_BOOL(&varRight);
3154 break;
3155 default:
3156 FIXME("Couldn't bitwise AND variant types %d,%d\n",
3157 leftvt,rightvt);
3158 }
3159
3160VarAnd_Exit:
3161 VariantClear(&varLeft);
3162 VariantClear(&varRight);
3163 VariantClear(&tempLeft);
3164 VariantClear(&tempRight);
3165
3166 return hres;
3167}
short VARIANT_BOOL
Definition: compat.h:2290
@ VT_I1
Definition: compat.h:2310
HRESULT WINAPI VarBoolFromStr(const OLECHAR *strIn, LCID lcid, ULONG dwFlags, VARIANT_BOOL *pBoolOut)
Definition: vartype.c:6139
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define d
Definition: ke_i.h:81
#define b
Definition: ke_i.h:79
#define V_UI1(A)
Definition: oleauto.h:266
#define V_BOOL(A)
Definition: oleauto.h:224
#define V_INT(A)
Definition: oleauto.h:251
#define V_UI2(A)
Definition: oleauto.h:268
#define V_I1(A)
Definition: oleauto.h:243
#define VAR_LOCALBOOL
Definition: oleauto.h:330
#define V_UINT(A)
Definition: oleauto.h:264
#define V_UI4(A)
Definition: oleauto.h:270
#define VARIANT_LOCALBOOL
Definition: oleauto.h:314
#define V_UI8(A)
Definition: oleauto.h:272
static const VARTYPE ExtraFlags[16]
Definition: vartest.c:638

Referenced by interp_and(), and test_VarAnd().

◆ VarCat()

HRESULT WINAPI VarCat ( LPVARIANT  left,
LPVARIANT  right,
LPVARIANT  out 
)

Definition at line 2580 of file variant.c.

2581{
2582 BSTR left_str = NULL, right_str = NULL;
2583 VARTYPE leftvt, rightvt;
2584 HRESULT hres;
2585
2587
2588 leftvt = V_VT(left);
2589 rightvt = V_VT(right);
2590
2591 /* when both left and right are NULL the result is NULL */
2592 if (leftvt == VT_NULL && rightvt == VT_NULL)
2593 {
2594 V_VT(out) = VT_NULL;
2595 return S_OK;
2596 }
2597
2598 /* There are many special case for errors and return types */
2599 if (leftvt == VT_VARIANT && (rightvt == VT_ERROR ||
2600 rightvt == VT_DATE || rightvt == VT_DECIMAL))
2602 else if ((leftvt == VT_I2 || leftvt == VT_I4 ||
2603 leftvt == VT_R4 || leftvt == VT_R8 ||
2604 leftvt == VT_CY || leftvt == VT_BOOL ||
2605 leftvt == VT_BSTR || leftvt == VT_I1 ||
2606 leftvt == VT_UI1 || leftvt == VT_UI2 ||
2607 leftvt == VT_UI4 || leftvt == VT_I8 ||
2608 leftvt == VT_UI8 || leftvt == VT_INT ||
2609 leftvt == VT_UINT || leftvt == VT_EMPTY ||
2610 leftvt == VT_NULL || leftvt == VT_DATE ||
2611 leftvt == VT_DECIMAL || leftvt == VT_DISPATCH)
2612 &&
2613 (rightvt == VT_I2 || rightvt == VT_I4 ||
2614 rightvt == VT_R4 || rightvt == VT_R8 ||
2615 rightvt == VT_CY || rightvt == VT_BOOL ||
2616 rightvt == VT_BSTR || rightvt == VT_I1 ||
2617 rightvt == VT_UI1 || rightvt == VT_UI2 ||
2618 rightvt == VT_UI4 || rightvt == VT_I8 ||
2619 rightvt == VT_UI8 || rightvt == VT_INT ||
2620 rightvt == VT_UINT || rightvt == VT_EMPTY ||
2621 rightvt == VT_NULL || rightvt == VT_DATE ||
2622 rightvt == VT_DECIMAL || rightvt == VT_DISPATCH))
2623 hres = S_OK;
2624 else if (rightvt == VT_ERROR && leftvt < VT_VOID)
2626 else if (leftvt == VT_ERROR && (rightvt == VT_DATE ||
2627 rightvt == VT_ERROR || rightvt == VT_DECIMAL))
2629 else if (rightvt == VT_DATE || rightvt == VT_ERROR ||
2630 rightvt == VT_DECIMAL)
2632 else if (leftvt == VT_ERROR || rightvt == VT_ERROR)
2634 else if (leftvt == VT_VARIANT)
2636 else if (rightvt == VT_VARIANT && (leftvt == VT_EMPTY ||
2637 leftvt == VT_NULL || leftvt == VT_I2 ||
2638 leftvt == VT_I4 || leftvt == VT_R4 ||
2639 leftvt == VT_R8 || leftvt == VT_CY ||
2640 leftvt == VT_DATE || leftvt == VT_BSTR ||
2641 leftvt == VT_BOOL || leftvt == VT_DECIMAL ||
2642 leftvt == VT_I1 || leftvt == VT_UI1 ||
2643 leftvt == VT_UI2 || leftvt == VT_UI4 ||
2644 leftvt == VT_I8 || leftvt == VT_UI8 ||
2645 leftvt == VT_INT || leftvt == VT_UINT))
2647 else
2649
2650 /* if result type is not S_OK, then no need to go further */
2651 if (hres != S_OK)
2652 {
2653 V_VT(out) = VT_EMPTY;
2654 return hres;
2655 }
2656
2657 if (leftvt == VT_BSTR)
2658 left_str = V_BSTR(left);
2659 else
2660 {
2661 VARIANT converted, *tmp = left;
2662
2663 VariantInit(&converted);
2664 if(leftvt == VT_DISPATCH)
2665 {
2666 hres = VARIANT_FetchDispatchValue(left, &converted);
2667 if(FAILED(hres))
2668 goto failed;
2669
2670 tmp = &converted;
2671 }
2672
2674 if (SUCCEEDED(hres))
2675 left_str = V_BSTR(&converted);
2676 else if (hres != DISP_E_TYPEMISMATCH)
2677 {
2678 VariantClear(&converted);
2679 goto failed;
2680 }
2681 }
2682
2683 if (rightvt == VT_BSTR)
2684 right_str = V_BSTR(right);
2685 else
2686 {
2687 VARIANT converted, *tmp = right;
2688
2689 VariantInit(&converted);
2690 if(rightvt == VT_DISPATCH)
2691 {
2692 hres = VARIANT_FetchDispatchValue(right, &converted);
2693 if(FAILED(hres))
2694 goto failed;
2695
2696 tmp = &converted;
2697 }
2698
2700 if (SUCCEEDED(hres))
2701 right_str = V_BSTR(&converted);
2702 else if (hres != DISP_E_TYPEMISMATCH)
2703 {
2704 VariantClear(&converted);
2705 goto failed;
2706 }
2707 }
2708
2709
2710 V_VT(out) = VT_BSTR;
2711 hres = VarBstrCat(left_str, right_str, &V_BSTR(out));
2712
2713failed:
2714 if(V_VT(left) != VT_BSTR)
2715 SysFreeString(left_str);
2716 if(V_VT(right) != VT_BSTR)
2717 SysFreeString(right_str);
2718 return hres;
2719}
#define NULL
Definition: types.h:112
OLECHAR * BSTR
Definition: compat.h:2293
@ VT_VOID
Definition: compat.h:2318
@ VT_VARIANT
Definition: compat.h:2307
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:273
#define VARIANT_ALPHABOOL
Definition: oleauto.h:311
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383

Referenced by interp_concat(), and test_VarCat().

◆ VarCmp()

HRESULT WINAPI VarCmp ( LPVARIANT  left,
LPVARIANT  right,
LCID  lcid,
DWORD  flags 
)

Definition at line 2777 of file variant.c.

2778{
2779 VARTYPE lvt, rvt, vt;
2780 VARIANT rv,lv;
2781 DWORD xmask;
2782 HRESULT rc;
2783
2784 TRACE("%s, %s, %#lx, %#lx.\n", debugstr_variant(left), debugstr_variant(right), lcid, flags);
2785
2786 lvt = V_VT(left) & VT_TYPEMASK;
2787 rvt = V_VT(right) & VT_TYPEMASK;
2788 xmask = (1 << lvt) | (1 << rvt);
2789
2790 /* If we have any flag set except VT_RESERVED bail out.
2791 Same for the left input variant type > VT_INT and for the
2792 right input variant type > VT_I8. Yes, VT_INT is only supported
2793 as left variant. Go figure */
2794 if (((V_VT(left) | V_VT(right)) & ~VT_TYPEMASK & ~VT_RESERVED) ||
2795 lvt > VT_INT || rvt > VT_I8) {
2796 return DISP_E_BADVARTYPE;
2797 }
2798
2799 /* Don't ask me why but native VarCmp cannot handle: VT_I1, VT_UI2, VT_UI4,
2800 VT_UINT and VT_UI8. Tested with DCOM98, Win2k, WinXP */
2801 if (rvt == VT_INT || xmask & (VTBIT_I1 | VTBIT_UI2 | VTBIT_UI4 | VTBIT_UI8 |
2803 return DISP_E_TYPEMISMATCH;
2804
2805 /* If both variants are VT_ERROR return VARCMP_EQ */
2806 if (xmask == VTBIT_ERROR)
2807 return VARCMP_EQ;
2808 else if (xmask & VTBIT_ERROR)
2809 return DISP_E_TYPEMISMATCH;
2810
2811 if (xmask & VTBIT_NULL)
2812 return VARCMP_NULL;
2813
2814 VariantInit(&lv);
2815 VariantInit(&rv);
2816
2817 /* Two BSTRs, ignore VT_RESERVED */
2818 if (xmask == VTBIT_BSTR)
2820
2821 /* A BSTR and another variant; we have to take care of VT_RESERVED */
2822 if (xmask & VTBIT_BSTR) {
2823 VARIANT *bstrv, *nonbv;
2824 VARTYPE nonbvt;
2825 int swap = 0;
2826
2827 /* Swap the variants so the BSTR is always on the left */
2828 if (lvt == VT_BSTR) {
2829 bstrv = left;
2830 nonbv = right;
2831 nonbvt = rvt;
2832 } else {
2833 swap = 1;
2834 bstrv = right;
2835 nonbv = left;
2836 nonbvt = lvt;
2837 }
2838
2839 /* BSTR and EMPTY: ignore VT_RESERVED */
2840 if (nonbvt == VT_EMPTY)
2841 rc = (!V_BSTR(bstrv) || !*V_BSTR(bstrv)) ? VARCMP_EQ : VARCMP_GT;
2842 else {
2843 VARTYPE breserv = V_VT(bstrv) & ~VT_TYPEMASK;
2844 VARTYPE nreserv = V_VT(nonbv) & ~VT_TYPEMASK;
2845
2846 if (!breserv && !nreserv)
2847 /* No VT_RESERVED set ==> BSTR always greater */
2848 rc = VARCMP_GT;
2849 else if (breserv && !nreserv) {
2850 /* BSTR has VT_RESERVED set. Do a string comparison */
2851 rc = VariantChangeTypeEx(&rv,nonbv,lcid,0,VT_BSTR);
2852 if (FAILED(rc))
2853 return rc;
2854 rc = VarBstrCmp(V_BSTR(bstrv), V_BSTR(&rv), lcid, flags);
2855 VariantClear(&rv);
2856 } else if (V_BSTR(bstrv) && *V_BSTR(bstrv)) {
2857 /* Non NULL nor empty BSTR */
2858 /* If the BSTR is not a number the BSTR is greater */
2859 rc = _VarChangeTypeExWrap(&lv,bstrv,lcid,0,VT_R8);
2860 if (FAILED(rc))
2861 rc = VARCMP_GT;
2862 else if (breserv && nreserv)
2863 /* FIXME: This is strange: with both VT_RESERVED set it
2864 looks like the result depends only on the sign of
2865 the BSTR number */
2866 rc = (V_R8(&lv) >= 0) ? VARCMP_GT : VARCMP_LT;
2867 else
2868 /* Numeric comparison, will be handled below.
2869 VARCMP_NULL used only to break out. */
2870 rc = VARCMP_NULL;
2871 VariantClear(&lv);
2872 VariantClear(&rv);
2873 } else
2874 /* Empty or NULL BSTR */
2875 rc = VARCMP_GT;
2876 }
2877 /* Fixup the return code if we swapped left and right */
2878 if (swap) {
2879 if (rc == VARCMP_GT)
2880 rc = VARCMP_LT;
2881 else if (rc == VARCMP_LT)
2882 rc = VARCMP_GT;
2883 }
2884 if (rc != VARCMP_NULL)
2885 return rc;
2886 }
2887
2888 if (xmask & VTBIT_DECIMAL)
2889 vt = VT_DECIMAL;
2890 else if (xmask & VTBIT_BSTR)
2891 vt = VT_R8;
2892 else if (xmask & VTBIT_R4)
2893 vt = VT_R4;
2894 else if (xmask & (VTBIT_R8 | VTBIT_DATE))
2895 vt = VT_R8;
2896 else if (xmask & VTBIT_CY)
2897 vt = VT_CY;
2898 else
2899 /* default to I8 */
2900 vt = VT_I8;
2901
2902 /* Coerce the variants */
2903 rc = _VarChangeTypeExWrap(&lv,left,lcid,0,vt);
2904 if (rc == DISP_E_OVERFLOW && vt != VT_R8) {
2905 /* Overflow, change to R8 */
2906 vt = VT_R8;
2907 rc = _VarChangeTypeExWrap(&lv,left,lcid,0,vt);
2908 }
2909 if (FAILED(rc))
2910 return rc;
2911 rc = _VarChangeTypeExWrap(&rv,right,lcid,0,vt);
2912 if (rc == DISP_E_OVERFLOW && vt != VT_R8) {
2913 /* Overflow, change to R8 */
2914 vt = VT_R8;
2915 rc = _VarChangeTypeExWrap(&lv,left,lcid,0,vt);
2916 if (FAILED(rc))
2917 return rc;
2918 rc = _VarChangeTypeExWrap(&rv,right,lcid,0,vt);
2919 }
2920 if (FAILED(rc))
2921 return rc;
2922
2923#define _VARCMP(a,b) \
2924 (((a) == (b)) ? VARCMP_EQ : (((a) < (b)) ? VARCMP_LT : VARCMP_GT))
2925
2926 switch (vt) {
2927 case VT_CY:
2928 return VarCyCmp(V_CY(&lv), V_CY(&rv));
2929 case VT_DECIMAL:
2930 return VarDecCmp(&V_DECIMAL(&lv), &V_DECIMAL(&rv));
2931 case VT_I8:
2932 return _VARCMP(V_I8(&lv), V_I8(&rv));
2933 case VT_R4:
2934 return _VARCMP(V_R4(&lv), V_R4(&rv));
2935 case VT_R8:
2936 return _VARCMP(V_R8(&lv), V_R8(&rv));
2937 default:
2938 /* We should never get here */
2939 return E_FAIL;
2940 }
2941#undef _VARCMP
2942}
#define E_FAIL
Definition: ddrawi.h:102
@ VT_RESERVED
Definition: compat.h:2343
HRESULT WINAPI VarDecCmp(const DECIMAL *pDecLeft, const DECIMAL *pDecRight)
Definition: vartype.c:5891
HRESULT WINAPI VarBstrCmp(BSTR pbstrLeft, BSTR pbstrRight, LCID lcid, DWORD dwFlags)
Definition: vartype.c:7219
HRESULT WINAPI VarCyCmp(CY cyLeft, CY cyRight)
Definition: vartype.c:4006
unsigned long DWORD
Definition: ntddk_ex.h:95
GLbitfield flags
Definition: glext.h:7161
#define VARCMP_LT
Definition: oleauto.h:657
#define VARCMP_NULL
Definition: oleauto.h:660
#define VTBIT_R4
Definition: oleauto.h:760
#define VARCMP_EQ
Definition: oleauto.h:658
#define VTBIT_CY
Definition: oleauto.h:762
#define VARCMP_GT
Definition: oleauto.h:659
#define VTBIT_DECIMAL
Definition: oleauto.h:763
#define VTBIT_UI8
Definition: oleauto.h:759
#define VTBIT_UI4
Definition: oleauto.h:757
#define VTBIT_UI2
Definition: oleauto.h:755
#define VTBIT_I1
Definition: oleauto.h:752
#define VTBIT_R8
Definition: oleauto.h:761
#define swap(a, b)
Definition: qsort.c:63
static HRESULT _VarChangeTypeExWrap(VARIANTARG *pvargDest, VARIANTARG *pvargSrc, LCID lcid, USHORT wFlags, VARTYPE vt)
Definition: variant.c:2724
#define _VARCMP(a, b)
#define VTBIT_15
Definition: variant.h:48
#define VTBIT_DISPATCH
Definition: variant.h:40
#define VTBIT_UNKNOWN
Definition: variant.h:46
#define VTBIT_BSTR
Definition: variant.h:38
#define VTBIT_DATE
Definition: variant.h:39
#define VTBIT_NULL
Definition: variant.h:44
#define VTBIT_ERROR
Definition: variant.h:42
#define VTBIT_VARIANT
Definition: variant.h:47

Referenced by interp_step(), submit_onclick_setret(), test_cmp(), test_VarCmp(), and var_cmp().

◆ VarDateFromUdate()

HRESULT WINAPI VarDateFromUdate ( UDATE pUdateIn,
ULONG  dwFlags,
DATE pDateOut 
)

Definition at line 1383 of file variant.c.

1384{
1386
1387 return VarDateFromUdateEx(pUdateIn, lcid, dwFlags, pDateOut);
1388}
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define SORT_DEFAULT
#define MAKELCID(lgid, srtid)
#define MAKELANGID(p, s)
Definition: nls.h:15
#define LANG_ENGLISH
Definition: nls.h:52
DWORD LCID
Definition: nls.h:13
#define SUBLANG_ENGLISH_US
Definition: nls.h:222
HRESULT WINAPI VarDateFromUdateEx(UDATE *pUdateIn, LCID lcid, ULONG dwFlags, DATE *pDateOut)
Definition: variant.c:1322

Referenced by DosDateTimeToVariantTime(), SystemTimeToVariantTime(), and test_DateFromUDate().

◆ VarDateFromUdateEx()

HRESULT WINAPI VarDateFromUdateEx ( UDATE pUdateIn,
LCID  lcid,
ULONG  dwFlags,
DATE pDateOut 
)

Definition at line 1322 of file variant.c.

1323{
1324 UDATE ud;
1325 double dateVal = 0;
1326
1327 TRACE("%p, %d/%d/%d, %d:%d:%d:%d, %#x, %d, %#lx, %#lx, %p.\n", pUdateIn,
1328 pUdateIn->st.wMonth, pUdateIn->st.wDay, pUdateIn->st.wYear,
1329 pUdateIn->st.wHour, pUdateIn->st.wMinute, pUdateIn->st.wSecond,
1330 pUdateIn->st.wMilliseconds, pUdateIn->st.wDayOfWeek,
1331 pUdateIn->wDayOfYear, lcid, dwFlags, pDateOut);
1332
1334 FIXME("lcid possibly not handled, treating as en-us\n");
1336 FIXME("unsupported flags: %lx\n", dwFlags);
1337
1338 ud = *pUdateIn;
1339
1340 if (dwFlags & VAR_VALIDDATE)
1341 WARN("Ignoring VAR_VALIDDATE\n");
1342
1343 if (FAILED(VARIANT_RollUdate(&ud)))
1344 return E_INVALIDARG;
1345
1346 /* Date */
1347 if (!(dwFlags & VAR_TIMEVALUEONLY))
1349
1351 {
1352 double dateSign = (dateVal < 0.0) ? -1.0 : 1.0;
1353
1354 /* Time */
1355 dateVal += ud.st.wHour / 24.0 * dateSign;
1356 dateVal += ud.st.wMinute / 1440.0 * dateSign;
1357 dateVal += ud.st.wSecond / 86400.0 * dateSign;
1358 }
1359
1360 TRACE("Returning %g\n", dateVal);
1361 *pDateOut = dateVal;
1362 return S_OK;
1363}
#define WARN(fmt,...)
Definition: precomp.h:61
#define E_INVALIDARG
Definition: ddrawi.h:101
#define VAR_DATEVALUEONLY
Definition: oleauto.h:327
#define VAR_TIMEVALUEONLY
Definition: oleauto.h:326
#define VAR_VALIDDATE
Definition: oleauto.h:328
USHORT wDayOfYear
Definition: oleauto.h:722
static double VARIANT_JulianFromDMY(USHORT year, USHORT month, USHORT day)
Definition: variant.c:1065
static int VARIANT_DateFromJulian(int dateIn)
Definition: variant.c:1038
static HRESULT VARIANT_RollUdate(UDATE *lpUd)
Definition: variant.c:1085

Referenced by Global_Date(), Global_DateAdd(), Global_DateSerial(), Global_Time(), Global_TimeSerial(), and VarDateFromUdate().

◆ VarDiv()

HRESULT WINAPI VarDiv ( LPVARIANT  left,
LPVARIANT  right,
LPVARIANT  result 
)

Definition at line 3585 of file variant.c.

3586{
3587 HRESULT hres = S_OK;
3588 VARTYPE resvt = VT_EMPTY;
3589 VARTYPE leftvt,rightvt;
3590 VARTYPE rightExtraFlags,leftExtraFlags,ExtraFlags;
3591 VARIANT lv,rv;
3592 VARIANT tempLeft, tempRight;
3593
3594 VariantInit(&tempLeft);
3595 VariantInit(&tempRight);
3596 VariantInit(&lv);
3597 VariantInit(&rv);
3598
3600
3601 /* Handle VT_DISPATCH by storing and taking address of returned value */
3602 if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
3603 {
3604 hres = VARIANT_FetchDispatchValue(left, &tempLeft);
3605 if (FAILED(hres)) goto end;
3606 left = &tempLeft;
3607 }
3608 if ((V_VT(right) & VT_TYPEMASK) == VT_DISPATCH)
3609 {
3610 hres = VARIANT_FetchDispatchValue(right, &tempRight);
3611 if (FAILED(hres)) goto end;
3612 right = &tempRight;
3613 }
3614
3615 leftvt = V_VT(left)&VT_TYPEMASK;
3616 rightvt = V_VT(right)&VT_TYPEMASK;
3617 leftExtraFlags = V_VT(left)&(~VT_TYPEMASK);
3618 rightExtraFlags = V_VT(right)&(~VT_TYPEMASK);
3619
3620 if (leftExtraFlags != rightExtraFlags)
3621 {
3623 goto end;
3624 }
3625 ExtraFlags = leftExtraFlags;
3626
3627 /* Native VarDiv always returns an error when using extra flags */
3628 if (ExtraFlags != 0)
3629 {
3631 goto end;
3632 }
3633
3634 /* Determine return type */
3635 if (rightvt != VT_EMPTY)
3636 {
3637 if (leftvt == VT_NULL || rightvt == VT_NULL)
3638 {
3639 V_VT(result) = VT_NULL;
3640 hres = S_OK;
3641 goto end;
3642 }
3643 else if (leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
3644 resvt = VT_DECIMAL;
3645 else if (leftvt == VT_I8 || rightvt == VT_I8 ||
3646 leftvt == VT_CY || rightvt == VT_CY ||
3647 leftvt == VT_DATE || rightvt == VT_DATE ||
3648 leftvt == VT_I4 || rightvt == VT_I4 ||
3649 leftvt == VT_BSTR || rightvt == VT_BSTR ||
3650 leftvt == VT_I2 || rightvt == VT_I2 ||
3651 leftvt == VT_BOOL || rightvt == VT_BOOL ||
3652 leftvt == VT_R8 || rightvt == VT_R8 ||
3653 leftvt == VT_UI1 || rightvt == VT_UI1)
3654 {
3655 if ((leftvt == VT_UI1 && rightvt == VT_R4) ||
3656 (leftvt == VT_R4 && rightvt == VT_UI1))
3657 resvt = VT_R4;
3658 else if ((leftvt == VT_R4 && (rightvt == VT_BOOL ||
3659 rightvt == VT_I2)) || (rightvt == VT_R4 &&
3660 (leftvt == VT_BOOL || leftvt == VT_I2)))
3661 resvt = VT_R4;
3662 else
3663 resvt = VT_R8;
3664 }
3665 else if (leftvt == VT_R4 || rightvt == VT_R4)
3666 resvt = VT_R4;
3667 }
3668 else if (leftvt == VT_NULL)
3669 {
3670 V_VT(result) = VT_NULL;
3671 hres = S_OK;
3672 goto end;
3673 }
3674 else
3675 {
3677 goto end;
3678 }
3679
3680 /* coerce to the result type */
3681 hres = VariantChangeType(&lv, left, 0, resvt);
3682 if (hres != S_OK) goto end;
3683
3684 hres = VariantChangeType(&rv, right, 0, resvt);
3685 if (hres != S_OK) goto end;
3686
3687 /* do the math */
3688 V_VT(result) = resvt;
3689 switch (resvt)
3690 {
3691 case VT_R4:
3692 if (V_R4(&lv) == 0.0 && V_R4(&rv) == 0.0)
3693 {
3695 V_VT(result) = VT_EMPTY;
3696 }
3697 else if (V_R4(&rv) == 0.0)
3698 {
3700 V_VT(result) = VT_EMPTY;
3701 }
3702 else
3703 V_R4(result) = V_R4(&lv) / V_R4(&rv);
3704 break;
3705 case VT_R8:
3706 if (V_R8(&lv) == 0.0 && V_R8(&rv) == 0.0)
3707 {
3709 V_VT(result) = VT_EMPTY;
3710 }
3711 else if (V_R8(&rv) == 0.0)
3712 {
3714 V_VT(result) = VT_EMPTY;
3715 }
3716 else
3717 V_R8(result) = V_R8(&lv) / V_R8(&rv);
3718 break;
3719 case VT_DECIMAL:
3720 hres = VarDecDiv(&(V_DECIMAL(&lv)), &(V_DECIMAL(&rv)), &(V_DECIMAL(result)));
3721 break;
3722 }
3723
3724end:
3725 VariantClear(&lv);
3726 VariantClear(&rv);
3727 VariantClear(&tempLeft);
3728 VariantClear(&tempRight);
3729 TRACE("returning %#lx, %s\n", hres, debugstr_variant(result));
3730 return hres;
3731}
HRESULT WINAPI VarDecDiv(const DECIMAL *pDecLeft, const DECIMAL *pDecRight, DECIMAL *pDecOut)
Definition: vartype.c:5626
#define DISP_E_DIVBYZERO
Definition: winerror.h:3630

Referenced by interp_div(), and test_VarDiv().

◆ VarEqv()

HRESULT WINAPI VarEqv ( LPVARIANT  pVarLeft,
LPVARIANT  pVarRight,
LPVARIANT  pVarOut 
)

Definition at line 4792 of file variant.c.

4793{
4794 HRESULT hRet;
4795
4796 TRACE("(%s,%s,%p)\n", debugstr_variant(pVarLeft), debugstr_variant(pVarRight), pVarOut);
4797
4798 hRet = VarXor(pVarLeft, pVarRight, pVarOut);
4799 if (SUCCEEDED(hRet))
4800 {
4801 if (V_VT(pVarOut) == VT_I8)
4802 V_I8(pVarOut) = ~V_I8(pVarOut);
4803 else
4804 V_UI4(pVarOut) = ~V_UI4(pVarOut);
4805 }
4806 return hRet;
4807}
HRESULT WINAPI VarXor(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
Definition: variant.c:4612

Referenced by interp_eqv(), and test_VarEqv().

◆ VarFix()

HRESULT WINAPI VarFix ( LPVARIANT  pVarIn,
LPVARIANT  pVarOut 
)

Definition at line 4433 of file variant.c.

4434{
4435 HRESULT hRet = S_OK;
4436 VARIANT temp;
4437
4438 VariantInit(&temp);
4439
4440 TRACE("(%s,%p)\n", debugstr_variant(pVarIn), pVarOut);
4441
4442 /* Handle VT_DISPATCH by storing and taking address of returned value */
4443 if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
4444 {
4445 hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
4446 if (FAILED(hRet)) goto VarFix_Exit;
4447 pVarIn = &temp;
4448 }
4449 V_VT(pVarOut) = V_VT(pVarIn);
4450
4451 switch (V_VT(pVarIn))
4452 {
4453 case VT_UI1:
4454 V_UI1(pVarOut) = V_UI1(pVarIn);
4455 break;
4456 case VT_BOOL:
4457 V_VT(pVarOut) = VT_I2;
4458 /* Fall through */
4459 case VT_I2:
4460 V_I2(pVarOut) = V_I2(pVarIn);
4461 break;
4462 case VT_I4:
4463 V_I4(pVarOut) = V_I4(pVarIn);
4464 break;
4465 case VT_I8:
4466 V_I8(pVarOut) = V_I8(pVarIn);
4467 break;
4468 case VT_R4:
4469 if (V_R4(pVarIn) < 0.0f)
4470 V_R4(pVarOut) = (float)ceil(V_R4(pVarIn));
4471 else
4472 V_R4(pVarOut) = (float)floor(V_R4(pVarIn));
4473 break;
4474 case VT_BSTR:
4475 V_VT(pVarOut) = VT_R8;
4476 hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(pVarOut));
4477 pVarIn = pVarOut;
4478 /* Fall through */
4479 case VT_DATE:
4480 case VT_R8:
4481 if (V_R8(pVarIn) < 0.0)
4482 V_R8(pVarOut) = ceil(V_R8(pVarIn));
4483 else
4484 V_R8(pVarOut) = floor(V_R8(pVarIn));
4485 break;
4486 case VT_CY:
4487 hRet = VarCyFix(V_CY(pVarIn), &V_CY(pVarOut));
4488 break;
4489 case VT_DECIMAL:
4490 hRet = VarDecFix(&V_DECIMAL(pVarIn), &V_DECIMAL(pVarOut));
4491 break;
4492 case VT_EMPTY:
4493 V_VT(pVarOut) = VT_I2;
4494 V_I2(pVarOut) = 0;
4495 break;
4496 case VT_NULL:
4497 /* No-Op */
4498 break;
4499 default:
4500 if (V_TYPE(pVarIn) == VT_CLSID || /* VT_CLSID is a special case */
4502 hRet = DISP_E_BADVARTYPE;
4503 else
4504 hRet = DISP_E_TYPEMISMATCH;
4505 }
4506VarFix_Exit:
4507 if (FAILED(hRet))
4508 V_VT(pVarOut) = VT_EMPTY;
4510
4511 return hRet;
4512}
@ VT_CLSID
Definition: compat.h:2337
_ACRTIMP double __cdecl ceil(double)
Definition: ceil.c:18
_ACRTIMP double __cdecl floor(double)
Definition: floor.c:18
HRESULT WINAPI VarCyFix(CY cyIn, CY *pCyOut)
Definition: vartype.c:3896
HRESULT WINAPI VarDecFix(const DECIMAL *pDecIn, DECIMAL *pDecOut)
Definition: vartype.c:5747
static float(__cdecl *square_half_float)(float x
static HRESULT VARIANT_ValidateType(VARTYPE vt)
Definition: variant.c:523
#define V_TYPE(v)
Definition: variant.h:28

Referenced by Global_Fix(), test_VarFix(), and VarInt().

◆ VARIANT_ClearInd()

HRESULT VARIANT_ClearInd ( VARIANTARG pVarg)

Definition at line 554 of file variant.c.

555{
557
558 TRACE("(%s)\n", debugstr_variant(pVarg));
559
561 if (FAILED(hres))
562 return hres;
563
564 switch (V_VT(pVarg))
565 {
566 case VT_DISPATCH:
567 case VT_UNKNOWN:
568 if (V_UNKNOWN(pVarg))
569 IUnknown_Release(V_UNKNOWN(pVarg));
570 break;
571 case VT_UNKNOWN | VT_BYREF:
572 case VT_DISPATCH | VT_BYREF:
573 if(*V_UNKNOWNREF(pVarg))
574 IUnknown_Release(*V_UNKNOWNREF(pVarg));
575 break;
576 case VT_BSTR:
577 SysFreeString(V_BSTR(pVarg));
578 break;
579 case VT_BSTR | VT_BYREF:
580 SysFreeString(*V_BSTRREF(pVarg));
581 break;
582 case VT_VARIANT | VT_BYREF:
584 break;
585 case VT_RECORD:
586 case VT_RECORD | VT_BYREF:
587 {
588 IRecordInfo *rec_info = V_RECORDINFO(pVarg);
589 if (rec_info)
590 {
591 IRecordInfo_RecordClear(rec_info, V_RECORD(pVarg));
592 IRecordInfo_Release(rec_info);
593 }
594 break;
595 }
596 default:
597 if (V_ISARRAY(pVarg) || (V_VT(pVarg) & ~VT_BYREF) == VT_SAFEARRAY)
598 {
599 if (V_ISBYREF(pVarg))
600 {
601 if (*V_ARRAYREF(pVarg))
603 }
604 else if (V_ARRAY(pVarg))
605 hres = SafeArrayDestroy(V_ARRAY(pVarg));
606 }
607 break;
608 }
609
610 V_VT(pVarg) = VT_EMPTY;
611 return hres;
612}
@ VT_BYREF
Definition: compat.h:2342
@ VT_SAFEARRAY
Definition: compat.h:2321
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
Definition: safearray.c:1347
#define V_ARRAY(A)
Definition: oleauto.h:222
#define V_ARRAYREF(A)
Definition: oleauto.h:223
#define V_RECORDINFO(A)
Definition: oleauto.h:214
#define V_BSTRREF(A)
Definition: oleauto.h:227
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define V_UNKNOWNREF(A)
Definition: oleauto.h:282
#define V_ISBYREF(A)
Definition: oleauto.h:217
#define V_VARIANTREF(A)
Definition: oleauto.h:283
#define V_RECORD(A)
Definition: oleauto.h:213

Referenced by ITypeInfo_fnInvoke().

◆ VARIANT_Coerce()

static HRESULT VARIANT_Coerce ( VARIANTARG pd,
LCID  lcid,
USHORT  wFlags,
VARIANTARG ps,
VARTYPE  vt 
)
inlinestatic

Definition at line 44 of file variant.c.

46{
48 VARTYPE vtFrom = V_TYPE(ps);
49 DWORD dwFlags = 0;
50
51 TRACE("%s, %#lx, 0x%04x, %s, %s.\n", debugstr_variant(pd), lcid, wFlags,
52 debugstr_variant(ps), debugstr_vt(vt));
53
54 if (vt == VT_BSTR || vtFrom == VT_BSTR)
55 {
56 /* All flags passed to low level function are only used for
57 * changing to or from strings. Map these here.
58 */
71 }
72
73 /* Map int/uint to i4/ui4 */
74 if (vt == VT_INT)
75 vt = VT_I4;
76 else if (vt == VT_UINT)
77 vt = VT_UI4;
78
79 if (vtFrom == VT_INT)
80 vtFrom = VT_I4;
81 else if (vtFrom == VT_UINT)
82 vtFrom = VT_UI4;
83
84 if (vt == vtFrom)
85 return VariantCopy(pd, ps);
86
87 if (wFlags & VARIANT_NOVALUEPROP && vtFrom == VT_DISPATCH && vt != VT_UNKNOWN)
88 {
89 /* VARIANT_NOVALUEPROP prevents IDispatch objects from being coerced by
90 * accessing the default object property.
91 */
93 }
94
95 switch (vt)
96 {
97 case VT_EMPTY:
98 if (vtFrom == VT_NULL)
100 /* ... Fall through */
101 case VT_NULL:
102 if (vtFrom <= VT_UINT && vtFrom != (VARTYPE)15 && vtFrom != VT_ERROR)
103 {
104 res = VariantClear( pd );
105 if (vt == VT_NULL && SUCCEEDED(res))
106 V_VT(pd) = VT_NULL;
107 }
108 return res;
109
110 case VT_I1:
111 switch (vtFrom)
112 {
113 case VT_EMPTY: V_I1(pd) = 0; return S_OK;
114 case VT_I2: return VarI1FromI2(V_I2(ps), &V_I1(pd));
115 case VT_I4: return VarI1FromI4(V_I4(ps), &V_I1(pd));
116 case VT_UI1: V_I1(pd) = V_UI1(ps); return S_OK;
117 case VT_UI2: return VarI1FromUI2(V_UI2(ps), &V_I1(pd));
118 case VT_UI4: return VarI1FromUI4(V_UI4(ps), &V_I1(pd));
119 case VT_I8: return VarI1FromI8(V_I8(ps), &V_I1(pd));
120 case VT_UI8: return VarI1FromUI8(V_UI8(ps), &V_I1(pd));
121 case VT_R4: return VarI1FromR4(V_R4(ps), &V_I1(pd));
122 case VT_R8: return VarI1FromR8(V_R8(ps), &V_I1(pd));
123 case VT_DATE: return VarI1FromDate(V_DATE(ps), &V_I1(pd));
124 case VT_BOOL: return VarI1FromBool(V_BOOL(ps), &V_I1(pd));
125 case VT_CY: return VarI1FromCy(V_CY(ps), &V_I1(pd));
126 case VT_DECIMAL: return VarI1FromDec(&V_DECIMAL(ps), &V_I1(pd) );
127 case VT_DISPATCH: return VarI1FromDisp(V_DISPATCH(ps), lcid, &V_I1(pd) );
128 case VT_BSTR: return VarI1FromStr(V_BSTR(ps), lcid, dwFlags, &V_I1(pd) );
129 }
130 break;
131
132 case VT_I2:
133 switch (vtFrom)
134 {
135 case VT_EMPTY: V_I2(pd) = 0; return S_OK;
136 case VT_I1: return VarI2FromI1(V_I1(ps), &V_I2(pd));
137 case VT_I4: return VarI2FromI4(V_I4(ps), &V_I2(pd));
138 case VT_UI1: return VarI2FromUI1(V_UI1(ps), &V_I2(pd));
139 case VT_UI2: V_I2(pd) = V_UI2(ps); return S_OK;
140 case VT_UI4: return VarI2FromUI4(V_UI4(ps), &V_I2(pd));
141 case VT_I8: return VarI2FromI8(V_I8(ps), &V_I2(pd));
142 case VT_UI8: return VarI2FromUI8(V_UI8(ps), &V_I2(pd));
143 case VT_R4: return VarI2FromR4(V_R4(ps), &V_I2(pd));
144 case VT_R8: return VarI2FromR8(V_R8(ps), &V_I2(pd));
145 case VT_DATE: return VarI2FromDate(V_DATE(ps), &V_I2(pd));
146 case VT_BOOL: return VarI2FromBool(V_BOOL(ps), &V_I2(pd));
147 case VT_CY: return VarI2FromCy(V_CY(ps), &V_I2(pd));
148 case VT_DECIMAL: return VarI2FromDec(&V_DECIMAL(ps), &V_I2(pd));
149 case VT_DISPATCH: return VarI2FromDisp(V_DISPATCH(ps), lcid, &V_I2(pd));
150 case VT_BSTR: return VarI2FromStr(V_BSTR(ps), lcid, dwFlags, &V_I2(pd));
151 }
152 break;
153
154 case VT_I4:
155 switch (vtFrom)
156 {
157 case VT_EMPTY: V_I4(pd) = 0; return S_OK;
158 case VT_I1: return VarI4FromI1(V_I1(ps), &V_I4(pd));
159 case VT_I2: return VarI4FromI2(V_I2(ps), &V_I4(pd));
160 case VT_UI1: return VarI4FromUI1(V_UI1(ps), &V_I4(pd));
161 case VT_UI2: return VarI4FromUI2(V_UI2(ps), &V_I4(pd));
162 case VT_UI4: V_I4(pd) = V_UI4(ps); return S_OK;
163 case VT_I8: return VarI4FromI8(V_I8(ps), &V_I4(pd));
164 case VT_UI8: return VarI4FromUI8(V_UI8(ps), &V_I4(pd));
165 case VT_R4: return VarI4FromR4(V_R4(ps), &V_I4(pd));
166 case VT_R8: return VarI4FromR8(V_R8(ps), &V_I4(pd));
167 case VT_DATE: return VarI4FromDate(V_DATE(ps), &V_I4(pd));
168 case VT_BOOL: return VarI4FromBool(V_BOOL(ps), &V_I4(pd));
169 case VT_CY: return VarI4FromCy(V_CY(ps), &V_I4(pd));
170 case VT_DECIMAL: return VarI4FromDec(&V_DECIMAL(ps), &V_I4(pd));
171 case VT_DISPATCH: return VarI4FromDisp(V_DISPATCH(ps), lcid, &V_I4(pd));
172 case VT_BSTR: return VarI4FromStr(V_BSTR(ps), lcid, dwFlags, &V_I4(pd));
173 }
174 break;
175
176 case VT_UI1:
177 switch (vtFrom)
178 {
179 case VT_EMPTY: V_UI1(pd) = 0; return S_OK;
180 case VT_I1: V_UI1(pd) = V_I1(ps); return S_OK;
181 case VT_I2: return VarUI1FromI2(V_I2(ps), &V_UI1(pd));
182 case VT_I4: return VarUI1FromI4(V_I4(ps), &V_UI1(pd));
183 case VT_UI2: return VarUI1FromUI2(V_UI2(ps), &V_UI1(pd));
184 case VT_UI4: return VarUI1FromUI4(V_UI4(ps), &V_UI1(pd));
185 case VT_I8: return VarUI1FromI8(V_I8(ps), &V_UI1(pd));
186 case VT_UI8: return VarUI1FromUI8(V_UI8(ps), &V_UI1(pd));
187 case VT_R4: return VarUI1FromR4(V_R4(ps), &V_UI1(pd));
188 case VT_R8: return VarUI1FromR8(V_R8(ps), &V_UI1(pd));
189 case VT_DATE: return VarUI1FromDate(V_DATE(ps), &V_UI1(pd));
190 case VT_BOOL: return VarUI1FromBool(V_BOOL(ps), &V_UI1(pd));
191 case VT_CY: return VarUI1FromCy(V_CY(ps), &V_UI1(pd));
192 case VT_DECIMAL: return VarUI1FromDec(&V_DECIMAL(ps), &V_UI1(pd));
193 case VT_DISPATCH: return VarUI1FromDisp(V_DISPATCH(ps), lcid, &V_UI1(pd));
194 case VT_BSTR: return VarUI1FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI1(pd));
195 }
196 break;
197
198 case VT_UI2:
199 switch (vtFrom)
200 {
201 case VT_EMPTY: V_UI2(pd) = 0; return S_OK;
202 case VT_I1: return VarUI2FromI1(V_I1(ps), &V_UI2(pd));
203 case VT_I2: V_UI2(pd) = V_I2(ps); return S_OK;
204 case VT_I4: return VarUI2FromI4(V_I4(ps), &V_UI2(pd));
205 case VT_UI1: return VarUI2FromUI1(V_UI1(ps), &V_UI2(pd));
206 case VT_UI4: return VarUI2FromUI4(V_UI4(ps), &V_UI2(pd));
207 case VT_I8: return VarUI4FromI8(V_I8(ps), &V_UI4(pd));
208 case VT_UI8: return VarUI4FromUI8(V_UI8(ps), &V_UI4(pd));
209 case VT_R4: return VarUI2FromR4(V_R4(ps), &V_UI2(pd));
210 case VT_R8: return VarUI2FromR8(V_R8(ps), &V_UI2(pd));
211 case VT_DATE: return VarUI2FromDate(V_DATE(ps), &V_UI2(pd));
212 case VT_BOOL: return VarUI2FromBool(V_BOOL(ps), &V_UI2(pd));
213 case VT_CY: return VarUI2FromCy(V_CY(ps), &V_UI2(pd));
214 case VT_DECIMAL: return VarUI2FromDec(&V_DECIMAL(ps), &V_UI2(pd));
215 case VT_DISPATCH: return VarUI2FromDisp(V_DISPATCH(ps), lcid, &V_UI2(pd));
216 case VT_BSTR: return VarUI2FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI2(pd));
217 }
218 break;
219
220 case VT_UI4:
221 switch (vtFrom)
222 {
223 case VT_EMPTY: V_UI4(pd) = 0; return S_OK;
224 case VT_I1: return VarUI4FromI1(V_I1(ps), &V_UI4(pd));
225 case VT_I2: return VarUI4FromI2(V_I2(ps), &V_UI4(pd));
226 case VT_I4: V_UI4(pd) = V_I4(ps); return S_OK;
227 case VT_UI1: return VarUI4FromUI1(V_UI1(ps), &V_UI4(pd));
228 case VT_UI2: return VarUI4FromUI2(V_UI2(ps), &V_UI4(pd));
229 case VT_I8: return VarUI4FromI8(V_I8(ps), &V_UI4(pd));
230 case VT_UI8: return VarUI4FromUI8(V_UI8(ps), &V_UI4(pd));
231 case VT_R4: return VarUI4FromR4(V_R4(ps), &V_UI4(pd));
232 case VT_R8: return VarUI4FromR8(V_R8(ps), &V_UI4(pd));
233 case VT_DATE: return VarUI4FromDate(V_DATE(ps), &V_UI4(pd));
234 case VT_BOOL: return VarUI4FromBool(V_BOOL(ps), &V_UI4(pd));
235 case VT_CY: return VarUI4FromCy(V_CY(ps), &V_UI4(pd));
236 case VT_DECIMAL: return VarUI4FromDec(&V_DECIMAL(ps), &V_UI4(pd));
237 case VT_DISPATCH: return VarUI4FromDisp(V_DISPATCH(ps), lcid, &V_UI4(pd));
238 case VT_BSTR: return VarUI4FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI4(pd));
239 }
240 break;
241
242 case VT_UI8:
243 switch (vtFrom)
244 {
245 case VT_EMPTY: V_UI8(pd) = 0; return S_OK;
246 case VT_I4: if (V_I4(ps) < 0) return DISP_E_OVERFLOW; V_UI8(pd) = V_I4(ps); return S_OK;
247 case VT_I1: return VarUI8FromI1(V_I1(ps), &V_UI8(pd));
248 case VT_I2: return VarUI8FromI2(V_I2(ps), &V_UI8(pd));
249 case VT_UI1: return VarUI8FromUI1(V_UI1(ps), &V_UI8(pd));
250 case VT_UI2: return VarUI8FromUI2(V_UI2(ps), &V_UI8(pd));
251 case VT_UI4: return VarUI8FromUI4(V_UI4(ps), &V_UI8(pd));
252 case VT_I8: V_UI8(pd) = V_I8(ps); return S_OK;
253 case VT_R4: return VarUI8FromR4(V_R4(ps), &V_UI8(pd));
254 case VT_R8: return VarUI8FromR8(V_R8(ps), &V_UI8(pd));
255 case VT_DATE: return VarUI8FromDate(V_DATE(ps), &V_UI8(pd));
256 case VT_BOOL: return VarUI8FromBool(V_BOOL(ps), &V_UI8(pd));
257 case VT_CY: return VarUI8FromCy(V_CY(ps), &V_UI8(pd));
258 case VT_DECIMAL: return VarUI8FromDec(&V_DECIMAL(ps), &V_UI8(pd));
259 case VT_DISPATCH: return VarUI8FromDisp(V_DISPATCH(ps), lcid, &V_UI8(pd));
260 case VT_BSTR: return VarUI8FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI8(pd));
261 }
262 break;
263
264 case VT_I8:
265 switch (vtFrom)
266 {
267 case VT_EMPTY: V_I8(pd) = 0; return S_OK;
268 case VT_I4: V_I8(pd) = V_I4(ps); return S_OK;
269 case VT_I1: return VarI8FromI1(V_I1(ps), &V_I8(pd));
270 case VT_I2: return VarI8FromI2(V_I2(ps), &V_I8(pd));
271 case VT_UI1: return VarI8FromUI1(V_UI1(ps), &V_I8(pd));
272 case VT_UI2: return VarI8FromUI2(V_UI2(ps), &V_I8(pd));
273 case VT_UI4: return VarI8FromUI4(V_UI4(ps), &V_I8(pd));
274 case VT_UI8: V_I8(pd) = V_UI8(ps); return S_OK;
275 case VT_R4: return VarI8FromR4(V_R4(ps), &V_I8(pd));
276 case VT_R8: return VarI8FromR8(V_R8(ps), &V_I8(pd));
277 case VT_DATE: return VarI8FromDate(V_DATE(ps), &V_I8(pd));
278 case VT_BOOL: return VarI8FromBool(V_BOOL(ps), &V_I8(pd));
279 case VT_CY: return VarI8FromCy(V_CY(ps), &V_I8(pd));
280 case VT_DECIMAL: return VarI8FromDec(&V_DECIMAL(ps), &V_I8(pd));
281 case VT_DISPATCH: return VarI8FromDisp(V_DISPATCH(ps), lcid, &V_I8(pd));
282 case VT_BSTR: return VarI8FromStr(V_BSTR(ps), lcid, dwFlags, &V_I8(pd));
283 }
284 break;
285
286 case VT_R4:
287 switch (vtFrom)
288 {
289 case VT_EMPTY: V_R4(pd) = 0.0f; return S_OK;
290 case VT_I1: return VarR4FromI1(V_I1(ps), &V_R4(pd));
291 case VT_I2: return VarR4FromI2(V_I2(ps), &V_R4(pd));
292 case VT_I4: return VarR4FromI4(V_I4(ps), &V_R4(pd));
293 case VT_UI1: return VarR4FromUI1(V_UI1(ps), &V_R4(pd));
294 case VT_UI2: return VarR4FromUI2(V_UI2(ps), &V_R4(pd));
295 case VT_UI4: return VarR4FromUI4(V_UI4(ps), &V_R4(pd));
296 case VT_I8: return VarR4FromI8(V_I8(ps), &V_R4(pd));
297 case VT_UI8: return VarR4FromUI8(V_UI8(ps), &V_R4(pd));
298 case VT_R8: return VarR4FromR8(V_R8(ps), &V_R4(pd));
299 case VT_DATE: return VarR4FromDate(V_DATE(ps), &V_R4(pd));
300 case VT_BOOL: return VarR4FromBool(V_BOOL(ps), &V_R4(pd));
301 case VT_CY: return VarR4FromCy(V_CY(ps), &V_R4(pd));
302 case VT_DECIMAL: return VarR4FromDec(&V_DECIMAL(ps), &V_R4(pd));
303 case VT_DISPATCH: return VarR4FromDisp(V_DISPATCH(ps), lcid, &V_R4(pd));
304 case VT_BSTR: return VarR4FromStr(V_BSTR(ps), lcid, dwFlags, &V_R4(pd));
305 }
306 break;
307
308 case VT_R8:
309 switch (vtFrom)
310 {
311 case VT_EMPTY: V_R8(pd) = 0.0; return S_OK;
312 case VT_I1: return VarR8FromI1(V_I1(ps), &V_R8(pd));
313 case VT_I2: return VarR8FromI2(V_I2(ps), &V_R8(pd));
314 case VT_I4: return VarR8FromI4(V_I4(ps), &V_R8(pd));
315 case VT_UI1: return VarR8FromUI1(V_UI1(ps), &V_R8(pd));
316 case VT_UI2: return VarR8FromUI2(V_UI2(ps), &V_R8(pd));
317 case VT_UI4: return VarR8FromUI4(V_UI4(ps), &V_R8(pd));
318 case VT_I8: return VarR8FromI8(V_I8(ps), &V_R8(pd));
319 case VT_UI8: return VarR8FromUI8(V_UI8(ps), &V_R8(pd));
320 case VT_R4: return VarR8FromR4(V_R4(ps), &V_R8(pd));
321 case VT_DATE: return VarR8FromDate(V_DATE(ps), &V_R8(pd));
322 case VT_BOOL: return VarR8FromBool(V_BOOL(ps), &V_R8(pd));
323 case VT_CY: return VarR8FromCy(V_CY(ps), &V_R8(pd));
324 case VT_DECIMAL: return VarR8FromDec(&V_DECIMAL(ps), &V_R8(pd));
325 case VT_DISPATCH: return VarR8FromDisp(V_DISPATCH(ps), lcid, &V_R8(pd));
326 case VT_BSTR: return VarR8FromStr(V_BSTR(ps), lcid, dwFlags, &V_R8(pd));
327 }
328 break;
329
330 case VT_DATE:
331 switch (vtFrom)
332 {
333 case VT_EMPTY: V_DATE(pd) = 0.0; return S_OK;
334 case VT_I1: return VarDateFromI1(V_I1(ps), &V_DATE(pd));
335 case VT_I2: return VarDateFromI2(V_I2(ps), &V_DATE(pd));
336 case VT_I4: return VarDateFromI4(V_I4(ps), &V_DATE(pd));
337 case VT_UI1: return VarDateFromUI1(V_UI1(ps), &V_DATE(pd));
338 case VT_UI2: return VarDateFromUI2(V_UI2(ps), &V_DATE(pd));
339 case VT_UI4: return VarDateFromUI4(V_UI4(ps), &V_DATE(pd));
340 case VT_I8: return VarDateFromI8(V_I8(ps), &V_DATE(pd));
341 case VT_UI8: return VarDateFromUI8(V_UI8(ps), &V_DATE(pd));
342 case VT_R4: return VarDateFromR4(V_R4(ps), &V_DATE(pd));
343 case VT_R8: return VarDateFromR8(V_R8(ps), &V_DATE(pd));
344 case VT_BOOL: return VarDateFromBool(V_BOOL(ps), &V_DATE(pd));
345 case VT_CY: return VarDateFromCy(V_CY(ps), &V_DATE(pd));
346 case VT_DECIMAL: return VarDateFromDec(&V_DECIMAL(ps), &V_DATE(pd));
347 case VT_DISPATCH: return VarDateFromDisp(V_DISPATCH(ps), lcid, &V_DATE(pd));
348 case VT_BSTR: return VarDateFromStr(V_BSTR(ps), lcid, dwFlags, &V_DATE(pd));
349 }
350 break;
351
352 case VT_BOOL:
353 switch (vtFrom)
354 {
355 case VT_EMPTY: V_BOOL(pd) = 0; return S_OK;
356 case VT_I1: return VarBoolFromI1(V_I1(ps), &V_BOOL(pd));
357 case VT_I2: return VarBoolFromI2(V_I2(ps), &V_BOOL(pd));
358 case VT_I4: return VarBoolFromI4(V_I4(ps), &V_BOOL(pd));
359 case VT_UI1: return VarBoolFromUI1(V_UI1(ps), &V_BOOL(pd));
360 case VT_UI2: return VarBoolFromUI2(V_UI2(ps), &V_BOOL(pd));
361 case VT_UI4: return VarBoolFromUI4(V_UI4(ps), &V_BOOL(pd));
362 case VT_I8: return VarBoolFromI8(V_I8(ps), &V_BOOL(pd));
363 case VT_UI8: return VarBoolFromUI8(V_UI8(ps), &V_BOOL(pd));
364 case VT_R4: return VarBoolFromR4(V_R4(ps), &V_BOOL(pd));
365 case VT_R8: return VarBoolFromR8(V_R8(ps), &V_BOOL(pd));
366 case VT_DATE: return VarBoolFromDate(V_DATE(ps), &V_BOOL(pd));
367 case VT_CY: return VarBoolFromCy(V_CY(ps), &V_BOOL(pd));
368 case VT_DECIMAL: return VarBoolFromDec(&V_DECIMAL(ps), &V_BOOL(pd));
369 case VT_DISPATCH: return VarBoolFromDisp(V_DISPATCH(ps), lcid, &V_BOOL(pd));
370 case VT_BSTR: return VarBoolFromStr(V_BSTR(ps), lcid, dwFlags, &V_BOOL(pd));
371 }
372 break;
373
374 case VT_BSTR:
375 switch (vtFrom)
376 {
377 case VT_EMPTY:
378 V_BSTR(pd) = SysAllocStringLen(NULL, 0);
379 return V_BSTR(pd) ? S_OK : E_OUTOFMEMORY;
380 case VT_BOOL:
382 return VarBstrFromBool(V_BOOL(ps), lcid, dwFlags, &V_BSTR(pd));
383 return VarBstrFromI2(V_BOOL(ps), lcid, dwFlags, &V_BSTR(pd));
384 case VT_I1: return VarBstrFromI1(V_I1(ps), lcid, dwFlags, &V_BSTR(pd));
385 case VT_I2: return VarBstrFromI2(V_I2(ps), lcid, dwFlags, &V_BSTR(pd));
386 case VT_I4: return VarBstrFromI4(V_I4(ps), lcid, dwFlags, &V_BSTR(pd));
387 case VT_UI1: return VarBstrFromUI1(V_UI1(ps), lcid, dwFlags, &V_BSTR(pd));
388 case VT_UI2: return VarBstrFromUI2(V_UI2(ps), lcid, dwFlags, &V_BSTR(pd));
389 case VT_UI4: return VarBstrFromUI4(V_UI4(ps), lcid, dwFlags, &V_BSTR(pd));
390 case VT_I8: return VarBstrFromI8(V_I8(ps), lcid, dwFlags, &V_BSTR(pd));
391 case VT_UI8: return VarBstrFromUI8(V_UI8(ps), lcid, dwFlags, &V_BSTR(pd));
392 case VT_R4: return VarBstrFromR4(V_R4(ps), lcid, dwFlags, &V_BSTR(pd));
393 case VT_R8: return VarBstrFromR8(V_R8(ps), lcid, dwFlags, &V_BSTR(pd));
394 case VT_DATE: return VarBstrFromDate(V_DATE(ps), lcid, dwFlags, &V_BSTR(pd));
395 case VT_CY: return VarBstrFromCy(V_CY(ps), lcid, dwFlags, &V_BSTR(pd));
396 case VT_DECIMAL: return VarBstrFromDec(&V_DECIMAL(ps), lcid, dwFlags, &V_BSTR(pd));
397 case VT_DISPATCH: return VarBstrFromDisp(V_DISPATCH(ps), lcid, dwFlags, &V_BSTR(pd));
398 }
399 break;
400
401 case VT_CY:
402 switch (vtFrom)
403 {
404 case VT_EMPTY: V_CY(pd).int64 = 0; return S_OK;
405 case VT_I1: return VarCyFromI1(V_I1(ps), &V_CY(pd));
406 case VT_I2: return VarCyFromI2(V_I2(ps), &V_CY(pd));
407 case VT_I4: return VarCyFromI4(V_I4(ps), &V_CY(pd));
408 case VT_UI1: return VarCyFromUI1(V_UI1(ps), &V_CY(pd));
409 case VT_UI2: return VarCyFromUI2(V_UI2(ps), &V_CY(pd));
410 case VT_UI4: return VarCyFromUI4(V_UI4(ps), &V_CY(pd));
411 case VT_I8: return VarCyFromI8(V_I8(ps), &V_CY(pd));
412 case VT_UI8: return VarCyFromUI8(V_UI8(ps), &V_CY(pd));
413 case VT_R4: return VarCyFromR4(V_R4(ps), &V_CY(pd));
414 case VT_R8: return VarCyFromR8(V_R8(ps), &V_CY(pd));
415 case VT_DATE: return VarCyFromDate(V_DATE(ps), &V_CY(pd));
416 case VT_BOOL: return VarCyFromBool(V_BOOL(ps), &V_CY(pd));
417 case VT_DECIMAL: return VarCyFromDec(&V_DECIMAL(ps), &V_CY(pd));
418 case VT_DISPATCH: return VarCyFromDisp(V_DISPATCH(ps), lcid, &V_CY(pd));
419 case VT_BSTR: return VarCyFromStr(V_BSTR(ps), lcid, dwFlags, &V_CY(pd));
420 }
421 break;
422
423 case VT_DECIMAL:
424 switch (vtFrom)
425 {
426 case VT_EMPTY:
427 case VT_BOOL:
428 V_DECIMAL(pd).sign = DECIMAL_POS;
429 V_DECIMAL(pd).scale = 0;
430 V_DECIMAL(pd).Hi32 = 0;
431 /* VarDecFromBool() coerces to -1/0, ChangeTypeEx() coerces to 1/0.
432 * VT_NULL and VT_EMPTY always give a 0 value.
433 */
434 V_DECIMAL(pd).Lo64 = vtFrom == VT_BOOL && V_BOOL(ps) ? 1 : 0;
435 return S_OK;
436 case VT_I1: return VarDecFromI1(V_I1(ps), &V_DECIMAL(pd));
437 case VT_I2: return VarDecFromI2(V_I2(ps), &V_DECIMAL(pd));
438 case VT_I4: return VarDecFromI4(V_I4(ps), &V_DECIMAL(pd));
439 case VT_UI1: return VarDecFromUI1(V_UI1(ps), &V_DECIMAL(pd));
440 case VT_UI2: return VarDecFromUI2(V_UI2(ps), &V_DECIMAL(pd));
441 case VT_UI4: return VarDecFromUI4(V_UI4(ps), &V_DECIMAL(pd));
442 case VT_I8: return VarDecFromI8(V_I8(ps), &V_DECIMAL(pd));
443 case VT_UI8: return VarDecFromUI8(V_UI8(ps), &V_DECIMAL(pd));
444 case VT_R4: return VarDecFromR4(V_R4(ps), &V_DECIMAL(pd));
445 case VT_R8: return VarDecFromR8(V_R8(ps), &V_DECIMAL(pd));
446 case VT_DATE: return VarDecFromDate(V_DATE(ps), &V_DECIMAL(pd));
447 case VT_CY: return VarDecFromCy(V_CY(ps), &V_DECIMAL(pd));
448 case VT_DISPATCH: return VarDecFromDisp(V_DISPATCH(ps), lcid, &V_DECIMAL(pd));
449 case VT_BSTR: return VarDecFromStr(V_BSTR(ps), lcid, dwFlags, &V_DECIMAL(pd));
450 }
451 break;
452
453 case VT_UNKNOWN:
454 switch (vtFrom)
455 {
456 case VT_DISPATCH:
457 if (V_DISPATCH(ps) == NULL)
458 {
459 V_UNKNOWN(pd) = NULL;
460 res = S_OK;
461 }
462 else
463 res = IDispatch_QueryInterface(V_DISPATCH(ps), &IID_IUnknown, (LPVOID*)&V_UNKNOWN(pd));
464 break;
465 }
466 break;
467
468 case VT_DISPATCH:
469 switch (vtFrom)
470 {
471 case VT_UNKNOWN:
472 if (V_UNKNOWN(ps) == NULL)
473 {
474 V_DISPATCH(pd) = NULL;
475 res = S_OK;
476 }
477 else
478 res = IUnknown_QueryInterface(V_UNKNOWN(ps), &IID_IDispatch, (LPVOID*)&V_DISPATCH(pd));
479 break;
480 }
481 break;
482
483 case VT_RECORD:
484 break;
485 }
486 return res;
487}
const GUID IID_IUnknown
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
HRESULT WINAPI VarUI1FromI4(LONG iIn, BYTE *pbOut)
Definition: vartype.c:603
HRESULT WINAPI VarUI8FromUI2(USHORT usIn, ULONG64 *pui64Out)
Definition: vartype.c:2622
HRESULT WINAPI VarI4FromUI8(ULONG64 ullIn, LONG *piOut)
Definition: vartype.c:1757
HRESULT WINAPI VarBstrFromUI1(BYTE bIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:6418
HRESULT WINAPI VarUI2FromCy(CY cyIn, USHORT *pusOut)
Definition: vartype.c:1305
HRESULT WINAPI VarUI8FromCy(CY cyIn, ULONG64 *pui64Out)
Definition: vartype.c:2492
HRESULT WINAPI VarCyFromR8(double dblIn, CY *pCyOut)
Definition: vartype.c:3497
HRESULT WINAPI VarI2FromUI1(BYTE bIn, SHORT *psOut)
Definition: vartype.c:894
HRESULT WINAPI VarR4FromI1(signed char cIn, float *pFltOut)
Definition: vartype.c:2882
HRESULT WINAPI VarBstrFromBool(VARIANT_BOOL boolIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:6913
HRESULT WINAPI VarCyFromUI1(BYTE bIn, CY *pCyOut)
Definition: vartype.c:3414
HRESULT WINAPI VarR4FromUI8(ULONG64 ullIn, float *pFltOut)
Definition: vartype.c:2997
HRESULT WINAPI VarI2FromBool(VARIANT_BOOL boolIn, SHORT *psOut)
Definition: vartype.c:1053
HRESULT WINAPI VarDateFromStr(const OLECHAR *strIn, LCID lcid, ULONG dwFlags, DATE *pdateOut)
Definition: vartype.c:7663
HRESULT WINAPI VarUI2FromDisp(IDispatch *pdispIn, LCID lcid, USHORT *pusOut)
Definition: vartype.c:1350
HRESULT WINAPI VarBoolFromUI1(BYTE bIn, VARIANT_BOOL *pBoolOut)
Definition: vartype.c:5965
HRESULT WINAPI VarUI1FromUI4(ULONG ulIn, BYTE *pbOut)
Definition: vartype.c:809
HRESULT WINAPI VarI1FromR8(double dblIn, signed char *pcOut)
Definition: vartype.c:355
HRESULT WINAPI VarI1FromR4(FLOAT fltIn, signed char *pcOut)
Definition: vartype.c:333
HRESULT WINAPI VarUI4FromDisp(IDispatch *pdispIn, LCID lcid, ULONG *pulOut)
Definition: vartype.c:1935
HRESULT WINAPI VarCyFromUI2(USHORT usIn, CY *pCyOut)
Definition: vartype.c:3656
HRESULT WINAPI VarI1FromDisp(IDispatch *pdispIn, LCID lcid, signed char *pcOut)
Definition: vartype.c:442
HRESULT WINAPI VarDecFromCy(CY cyIn, DECIMAL *pDecOut)
Definition: vartype.c:4234
HRESULT WINAPI VarR8FromI2(SHORT sIn, double *pDblOut)
Definition: vartype.c:3056
HRESULT WINAPI VarUI4FromUI2(USHORT usIn, ULONG *pulOut)
Definition: vartype.c:1987
HRESULT WINAPI VarI1FromUI2(USHORT usIn, signed char *pcOut)
Definition: vartype.c:478
HRESULT WINAPI VarR8FromCy(CY cyIn, double *pDblOut)
Definition: vartype.c:3107
HRESULT WINAPI VarI1FromUI4(ULONG ulIn, signed char *pcOut)
Definition: vartype.c:498
HRESULT WINAPI VarBstrFromR8(double dblIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:6648
HRESULT WINAPI VarUI4FromI1(signed char cIn, ULONG *pulOut)
Definition: vartype.c:1970
HRESULT WINAPI VarI4FromStr(const OLECHAR *strIn, LCID lcid, ULONG dwFlags, LONG *piOut)
Definition: vartype.c:1605
HRESULT WINAPI VarI2FromUI8(ULONG64 ullIn, SHORT *psOut)
Definition: vartype.c:1168
HRESULT WINAPI VarI8FromUI1(BYTE bIn, LONG64 *pi64Out)
Definition: vartype.c:2069
HRESULT WINAPI VarBstrFromI2(short sIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:6439
HRESULT WINAPI VarI4FromBool(VARIANT_BOOL boolIn, LONG *piOut)
Definition: vartype.c:1643
HRESULT WINAPI VarUI8FromUI4(ULONG ulIn, ULONG64 *pui64Out)
Definition: vartype.c:2639
HRESULT WINAPI VarI8FromDisp(IDispatch *pdispIn, LCID lcid, LONG64 *pi64Out)
Definition: vartype.c:2242
HRESULT WINAPI VarUI1FromR8(double dblIn, BYTE *pbOut)
Definition: vartype.c:645
HRESULT WINAPI VarI1FromI2(SHORT sIn, signed char *pcOut)
Definition: vartype.c:295
HRESULT WINAPI VarDateFromDisp(IDispatch *pdispIn, LCID lcid, DATE *pdateOut)
Definition: vartype.c:7376
HRESULT WINAPI VarBstrFromI4(LONG lIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:6467
HRESULT WINAPI VarDecFromI2(SHORT sIn, DECIMAL *pDecOut)
Definition: vartype.c:4108
HRESULT WINAPI VarI8FromR8(double dblIn, LONG64 *pi64Out)
Definition: vartype.c:2142
HRESULT WINAPI VarR8FromI8(LONG64 llIn, double *pDblOut)
Definition: vartype.c:3300
HRESULT WINAPI VarR4FromDisp(IDispatch *pdispIn, LCID lcid, float *pFltOut)
Definition: vartype.c:2845
HRESULT WINAPI VarDateFromI1(signed char cIn, DATE *pdateOut)
Definition: vartype.c:8023
HRESULT WINAPI VarUI2FromI1(signed char cIn, USHORT *pusOut)
Definition: vartype.c:1385
HRESULT WINAPI VarDecFromUI1(BYTE bIn, DECIMAL *pDecOut)
Definition: vartype.c:4091
HRESULT WINAPI VarUI2FromI4(LONG iIn, USHORT *pusOut)
Definition: vartype.c:1224
HRESULT WINAPI VarUI1FromR4(FLOAT fltIn, BYTE *pbOut)
Definition: vartype.c:623
HRESULT WINAPI VarDecFromR8(double dblIn, DECIMAL *pDecOut)
Definition: vartype.c:4195
HRESULT WINAPI VarI4FromI2(SHORT sIn, LONG *piOut)
Definition: vartype.c:1504
HRESULT WINAPI VarDateFromUI8(ULONG64 ullIn, DATE *pdateOut)
Definition: vartype.c:8112
HRESULT WINAPI VarDateFromR4(FLOAT fltIn, DATE *pdateOut)
Definition: vartype.c:7336
HRESULT WINAPI VarBoolFromI8(LONG64 llIn, VARIANT_BOOL *pBoolOut)
Definition: vartype.c:6324
HRESULT WINAPI VarI1FromI4(LONG iIn, signed char *pcOut)
Definition: vartype.c:314
HRESULT WINAPI VarI4FromUI2(USHORT usIn, LONG *piOut)
Definition: vartype.c:1677
HRESULT WINAPI VarI8FromDate(DATE dateIn, LONG64 *pi64Out)
Definition: vartype.c:2199
HRESULT WINAPI VarI4FromDate(DATE dateIn, LONG *piOut)
Definition: vartype.c:1583
HRESULT WINAPI VarI8FromCy(CY cyIn, LONG64 *pi64Out)
Definition: vartype.c:2168
HRESULT WINAPI VarBstrFromCy(CY cyIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:6669
HRESULT WINAPI VarUI8FromBool(VARIANT_BOOL boolIn, ULONG64 *pui64Out)
Definition: vartype.c:2588
HRESULT WINAPI VarI1FromStr(const OLECHAR *strIn, LCID lcid, ULONG dwFlags, signed char *pcOut)
Definition: vartype.c:421
HRESULT WINAPI VarI8FromI2(SHORT sIn, LONG64 *pi64Out)
Definition: vartype.c:2087
HRESULT WINAPI VarR8FromUI2(USHORT usIn, double *pDblOut)
Definition: vartype.c:3223
HRESULT WINAPI VarUI8FromR4(FLOAT fltIn, ULONG64 *pui64Out)
Definition: vartype.c:2445
HRESULT WINAPI VarUI1FromCy(CY cyIn, BYTE *pbOut)
Definition: vartype.c:670
HRESULT WINAPI VarBoolFromI2(SHORT sIn, VARIANT_BOOL *pBoolOut)
Definition: vartype.c:5983
HRESULT WINAPI VarI2FromStr(const OLECHAR *strIn, LCID lcid, ULONG dwFlags, SHORT *psOut)
Definition: vartype.c:1015
HRESULT WINAPI VarDateFromUI1(BYTE bIn, DATE *pdateOut)
Definition: vartype.c:7285
HRESULT WINAPI VarR8FromDate(DATE dateIn, double *pDblOut)
Definition: vartype.c:3124
HRESULT WINAPI VarDecFromDisp(IDispatch *pdispIn, LCID lcid, DECIMAL *pDecOut)
Definition: vartype.c:4286
HRESULT WINAPI VarR4FromUI4(ULONG ulIn, float *pFltOut)
Definition: vartype.c:2922
HRESULT WINAPI VarCyFromBool(VARIANT_BOOL boolIn, CY *pCyOut)
Definition: vartype.c:3614
HRESULT WINAPI VarI4FromDisp(IDispatch *pdispIn, LCID lcid, LONG *piOut)
Definition: vartype.c:1626
HRESULT WINAPI VarI2FromI1(signed char cIn, SHORT *psOut)
Definition: vartype.c:1070
HRESULT WINAPI VarUI4FromDec(const DECIMAL *pdecIn, ULONG *pulOut)
Definition: vartype.c:2006
HRESULT WINAPI VarCyFromDate(DATE dateIn, CY *pCyOut)
Definition: vartype.c:3547
HRESULT WINAPI VarI4FromR8(double dblIn, LONG *piOut)
Definition: vartype.c:1543
HRESULT WINAPI VarI8FromR4(FLOAT fltIn, LONG64 *pi64Out)
Definition: vartype.c:2106
HRESULT WINAPI VarBoolFromI4(LONG lIn, VARIANT_BOOL *pBoolOut)
Definition: vartype.c:6001
HRESULT WINAPI VarR4FromUI1(BYTE bIn, float *pFltOut)
Definition: vartype.c:2712
HRESULT WINAPI VarI4FromI1(signed char cIn, LONG *piOut)
Definition: vartype.c:1660
HRESULT WINAPI VarBoolFromCy(CY cyIn, VARIANT_BOOL *pBoolOut)
Definition: vartype.c:6073
HRESULT WINAPI VarR4FromDec(const DECIMAL *pDecIn, float *pFltOut)
Definition: vartype.c:2940
HRESULT WINAPI VarI2FromDate(DATE dateIn, SHORT *psOut)
Definition: vartype.c:993
HRESULT WINAPI VarUI1FromUI8(ULONG64 ullIn, BYTE *pbOut)
Definition: vartype.c:873
HRESULT WINAPI VarDecFromR4(FLOAT fltIn, DECIMAL *pDecOut)
Definition: vartype.c:4173
HRESULT WINAPI VarUI4FromR8(double dblIn, ULONG *pulOut)
Definition: vartype.c:1852
HRESULT WINAPI VarBstrFromDate(DATE dateIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:6839
HRESULT WINAPI VarI2FromI8(LONG64 llIn, SHORT *psOut)
Definition: vartype.c:1150
HRESULT WINAPI VarBoolFromR4(FLOAT fltIn, VARIANT_BOOL *pBoolOut)
Definition: vartype.c:6019
HRESULT WINAPI VarUI2FromStr(const OLECHAR *strIn, LCID lcid, ULONG dwFlags, USHORT *pusOut)
Definition: vartype.c:1329
HRESULT WINAPI VarR8FromUI8(ULONG64 ullIn, double *pDblOut)
Definition: vartype.c:3317
HRESULT WINAPI VarUI4FromI2(SHORT sIn, ULONG *pulOut)
Definition: vartype.c:1795
HRESULT WINAPI VarR4FromCy(CY cyIn, float *pFltOut)
Definition: vartype.c:2784
HRESULT WINAPI VarCyFromDec(const DECIMAL *pdecIn, CY *pCyOut)
Definition: vartype.c:3698
HRESULT WINAPI VarUI1FromI2(SHORT sIn, BYTE *pbOut)
Definition: vartype.c:584
HRESULT WINAPI VarI2FromDec(const DECIMAL *pdecIn, SHORT *psOut)
Definition: vartype.c:1125
HRESULT WINAPI VarI4FromI8(LONG64 llIn, LONG *piOut)
Definition: vartype.c:1739
HRESULT WINAPI VarUI8FromR8(double dblIn, ULONG64 *pui64Out)
Definition: vartype.c:2467
HRESULT WINAPI VarUI8FromDate(DATE dateIn, ULONG64 *pui64Out)
Definition: vartype.c:2527
HRESULT WINAPI VarI8FromI1(signed char cIn, LONG64 *pi64Out)
Definition: vartype.c:2276
HRESULT WINAPI VarR4FromI2(SHORT sIn, float *pFltOut)
Definition: vartype.c:2729
HRESULT WINAPI VarI1FromUI8(ULONG64 ullIn, signed char *pcOut)
Definition: vartype.c:562
HRESULT WINAPI VarUI8FromStr(const OLECHAR *strIn, LCID lcid, ULONG dwFlags, ULONG64 *pui64Out)
Definition: vartype.c:2549
HRESULT WINAPI VarUI8FromDisp(IDispatch *pdispIn, LCID lcid, ULONG64 *pui64Out)
Definition: vartype.c:2570
HRESULT WINAPI VarUI4FromI8(LONG64 llIn, ULONG *pulOut)
Definition: vartype.c:2031
HRESULT WINAPI VarR8FromUI4(ULONG ulIn, double *pDblOut)
Definition: vartype.c:3243
HRESULT WINAPI VarUI1FromDec(const DECIMAL *pdecIn, BYTE *pbOut)
Definition: vartype.c:828
HRESULT WINAPI VarUI2FromDec(const DECIMAL *pdecIn, USHORT *pusOut)
Definition: vartype.c:1422
HRESULT WINAPI VarI4FromDec(const DECIMAL *pdecIn, LONG *piOut)
Definition: vartype.c:1714
HRESULT WINAPI VarUI2FromDate(DATE dateIn, USHORT *pusOut)
Definition: vartype.c:1284
HRESULT WINAPI VarDecFromUI8(ULONG64 ullIn, DECIMAL *pDecOut)
Definition: vartype.c:4420
HRESULT WINAPI VarI2FromDisp(IDispatch *pdispIn, LCID lcid, SHORT *psOut)
Definition: vartype.c:1036
HRESULT WINAPI VarDateFromCy(CY cyIn, DATE *pdateOut)
Definition: vartype.c:7410
HRESULT WINAPI VarUI2FromUI1(BYTE bIn, USHORT *pusOut)
Definition: vartype.c:1188
HRESULT WINAPI VarBoolFromDate(DATE dateIn, VARIANT_BOOL *pBoolOut)
Definition: vartype.c:6055
HRESULT WINAPI VarDateFromUI4(ULONG ulIn, DATE *pdateOut)
Definition: vartype.c:8057
HRESULT WINAPI VarR8FromI4(LONG lIn, double *pDblOut)
Definition: vartype.c:3073
HRESULT WINAPI VarDecFromUI2(USHORT usIn, DECIMAL *pDecOut)
Definition: vartype.c:4352
HRESULT WINAPI VarCyFromI8(LONG64 llIn, CY *pCyOut)
Definition: vartype.c:3736
HRESULT WINAPI VarDateFromBool(VARIANT_BOOL boolIn, DATE *pdateOut)
Definition: vartype.c:7393
HRESULT WINAPI VarI1FromDec(const DECIMAL *pdecIn, signed char *pcOut)
Definition: vartype.c:517
HRESULT WINAPI VarI2FromR8(double dblIn, SHORT *psOut)
Definition: vartype.c:951
HRESULT WINAPI VarI1FromBool(VARIANT_BOOL boolIn, signed char *pcOut)
Definition: vartype.c:459
HRESULT WINAPI VarR4FromUI2(USHORT usIn, float *pFltOut)
Definition: vartype.c:2902
HRESULT WINAPI VarUI4FromUI8(ULONG64 ullIn, ULONG *pulOut)
Definition: vartype.c:2049
HRESULT WINAPI VarBstrFromI8(LONG64 llIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:7099
HRESULT WINAPI VarUI4FromStr(const OLECHAR *strIn, LCID lcid, ULONG dwFlags, ULONG *pulOut)
Definition: vartype.c:1914
HRESULT WINAPI VarUI2FromBool(VARIANT_BOOL boolIn, USHORT *pusOut)
Definition: vartype.c:1367
HRESULT WINAPI VarUI1FromUI2(USHORT usIn, BYTE *pbOut)
Definition: vartype.c:790
HRESULT WINAPI VarDecFromUI4(ULONG ulIn, DECIMAL *pDecOut)
Definition: vartype.c:4369
HRESULT WINAPI VarUI1FromI8(LONG64 llIn, BYTE *pbOut)
Definition: vartype.c:854
HRESULT WINAPI VarI2FromR4(FLOAT fltIn, SHORT *psOut)
Definition: vartype.c:930
HRESULT WINAPI VarDecFromI4(LONG lIn, DECIMAL *pDecOut)
Definition: vartype.c:4125
HRESULT WINAPI VarBstrFromUI8(ULONG64 ullIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:7127
HRESULT WINAPI VarI4FromCy(CY cyIn, LONG *piOut)
Definition: vartype.c:1564
HRESULT WINAPI VarBoolFromUI8(ULONG64 ullIn, VARIANT_BOOL *pBoolOut)
Definition: vartype.c:6342
HRESULT WINAPI VarUI4FromR4(FLOAT fltIn, ULONG *pulOut)
Definition: vartype.c:1831
HRESULT WINAPI VarR8FromDisp(IDispatch *pdispIn, LCID lcid, double *pDblOut)
Definition: vartype.c:3166
HRESULT WINAPI VarUI2FromUI4(ULONG ulIn, USHORT *pusOut)
Definition: vartype.c:1403
HRESULT WINAPI VarBoolFromDec(const DECIMAL *pDecIn, VARIANT_BOOL *pBoolOut)
Definition: vartype.c:6300
HRESULT WINAPI VarUI1FromDisp(IDispatch *pdispIn, LCID lcid, BYTE *pbOut)
Definition: vartype.c:735
HRESULT WINAPI VarUI1FromBool(VARIANT_BOOL boolIn, BYTE *pbOut)
Definition: vartype.c:752
HRESULT WINAPI VarBoolFromDisp(IDispatch *pdispIn, LCID lcid, VARIANT_BOOL *pBoolOut)
Definition: vartype.c:6228
HRESULT WINAPI VarCyFromR4(FLOAT fltIn, CY *pCyOut)
Definition: vartype.c:3477
HRESULT WINAPI VarR4FromDate(DATE dateIn, float *pFltOut)
Definition: vartype.c:2803
HRESULT WINAPI VarI4FromUI1(BYTE bIn, LONG *piOut)
Definition: vartype.c:1485
HRESULT WINAPI VarR4FromI4(LONG lIn, float *pFltOut)
Definition: vartype.c:2746
HRESULT WINAPI VarCyFromI4(LONG lIn, CY *pCyOut)
Definition: vartype.c:3456
HRESULT WINAPI VarBoolFromUI2(USHORT usIn, VARIANT_BOOL *pBoolOut)
Definition: vartype.c:6263
HRESULT WINAPI VarCyFromDisp(IDispatch *pdispIn, LCID lcid, CY *pCyOut)
Definition: vartype.c:3590
HRESULT WINAPI VarI2FromUI4(ULONG ulIn, SHORT *psOut)
Definition: vartype.c:1106
HRESULT WINAPI VarUI4FromBool(VARIANT_BOOL boolIn, ULONG *pulOut)
Definition: vartype.c:1952
HRESULT WINAPI VarI8FromStr(const OLECHAR *strIn, LCID lcid, ULONG dwFlags, LONG64 *pi64Out)
Definition: vartype.c:2221
HRESULT WINAPI VarCyFromUI8(ULONG64 ullIn, CY *pCyOut)
Definition: vartype.c:3758
HRESULT WINAPI VarI8FromUI4(ULONG ulIn, LONG64 *pi64Out)
Definition: vartype.c:2310
HRESULT WINAPI VarUI4FromCy(CY cyIn, ULONG *pulOut)
Definition: vartype.c:1891
HRESULT WINAPI VarUI8FromUI1(BYTE bIn, ULONG64 *pui64Out)
Definition: vartype.c:2410
HRESULT WINAPI VarR8FromI1(signed char cIn, double *pDblOut)
Definition: vartype.c:3203
HRESULT WINAPI VarR4FromBool(VARIANT_BOOL boolIn, float *pFltOut)
Definition: vartype.c:2862
HRESULT WINAPI VarI8FromDec(const DECIMAL *pdecIn, LONG64 *pi64Out)
Definition: vartype.c:2329
HRESULT WINAPI VarR8FromDec(const DECIMAL *pDecIn, double *pDblOut)
Definition: vartype.c:3261
HRESULT WINAPI VarUI8FromI2(SHORT sIn, ULONG64 *pui64Out)
Definition: vartype.c:2427
HRESULT WINAPI VarBstrFromR4(FLOAT fltIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:6627
HRESULT WINAPI VarBoolFromR8(double dblIn, VARIANT_BOOL *pBoolOut)
Definition: vartype.c:6037
HRESULT WINAPI VarUI1FromDate(DATE dateIn, BYTE *pbOut)
Definition: vartype.c:692
HRESULT WINAPI VarBoolFromUI4(ULONG ulIn, VARIANT_BOOL *pBoolOut)
Definition: vartype.c:6281
HRESULT WINAPI VarR8FromUI1(BYTE bIn, double *pDblOut)
Definition: vartype.c:3039
HRESULT WINAPI VarDecFromDate(DATE dateIn, DECIMAL *pDecOut)
Definition: vartype.c:4217
HRESULT WINAPI VarBstrFromDisp(IDispatch *pdispIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:7148
HRESULT WINAPI VarR4FromI8(LONG64 llIn, float *pFltOut)
Definition: vartype.c:2980
HRESULT WINAPI VarR8FromBool(VARIANT_BOOL boolIn, double *pDblOut)
Definition: vartype.c:3183
HRESULT WINAPI VarUI8FromDec(const DECIMAL *pdecIn, ULONG64 *pui64Out)
Definition: vartype.c:2664
HRESULT WINAPI VarI1FromI8(LONG64 llIn, signed char *pcOut)
Definition: vartype.c:543
HRESULT WINAPI VarCyFromUI4(ULONG ulIn, CY *pCyOut)
Definition: vartype.c:3677
HRESULT WINAPI VarDateFromUI2(USHORT uiIn, DATE *pdateOut)
Definition: vartype.c:8040
HRESULT WINAPI VarDateFromR8(double dblIn, DATE *pdateOut)
Definition: vartype.c:7353
HRESULT WINAPI VarBstrFromDec(const DECIMAL *pDecIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:7052
HRESULT WINAPI VarI1FromDate(DATE dateIn, signed char *pcOut)
Definition: vartype.c:377
HRESULT WINAPI VarDateFromI2(short sIn, DATE *pdateOut)
Definition: vartype.c:7302
HRESULT WINAPI VarI2FromCy(CY cyIn, SHORT *psOut)
Definition: vartype.c:972
HRESULT WINAPI VarI1FromCy(CY cyIn, signed char *pcOut)
Definition: vartype.c:396
HRESULT WINAPI VarUI4FromDate(DATE dateIn, ULONG *pulOut)
Definition: vartype.c:1873
HRESULT WINAPI VarDateFromI4(LONG lIn, DATE *pdateOut)
Definition: vartype.c:7319
HRESULT WINAPI VarUI4FromUI1(BYTE bIn, ULONG *pulOut)
Definition: vartype.c:1777
HRESULT WINAPI VarBstrFromUI2(USHORT usIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:7010
HRESULT WINAPI VarI8FromBool(VARIANT_BOOL boolIn, LONG64 *pi64Out)
Definition: vartype.c:2259
HRESULT WINAPI VarDecFromI1(signed char cIn, DECIMAL *pDecOut)
Definition: vartype.c:4335
HRESULT WINAPI VarI8FromUI2(USHORT usIn, LONG64 *pi64Out)
Definition: vartype.c:2293
HRESULT WINAPI VarDateFromI8(LONG64 llIn, DATE *pdateOut)
Definition: vartype.c:8092
HRESULT WINAPI VarUI2FromR4(FLOAT fltIn, USHORT *pusOut)
Definition: vartype.c:1242
HRESULT WINAPI VarCyFromStr(const OLECHAR *strIn, LCID lcid, ULONG dwFlags, CY *pCyOut)
Definition: vartype.c:3569
HRESULT WINAPI VarUI2FromR8(double dblIn, USHORT *pusOut)
Definition: vartype.c:1263
HRESULT WINAPI VarI2FromI4(LONG iIn, SHORT *psOut)
Definition: vartype.c:912
HRESULT WINAPI VarDecFromStr(const OLECHAR *strIn, LCID lcid, ULONG dwFlags, DECIMAL *pDecOut)
Definition: vartype.c:4267
HRESULT WINAPI VarUI1FromStr(const OLECHAR *strIn, LCID lcid, ULONG dwFlags, BYTE *pbOut)
Definition: vartype.c:714
HRESULT WINAPI VarBoolFromI1(signed char cIn, VARIANT_BOOL *pBoolOut)
Definition: vartype.c:6245
HRESULT WINAPI VarUI8FromI1(signed char cIn, ULONG64 *pui64Out)
Definition: vartype.c:2605
HRESULT WINAPI VarBstrFromUI4(ULONG ulIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:7031
HRESULT WINAPI VarR4FromR8(double dblIn, float *pFltOut)
Definition: vartype.c:2764
HRESULT WINAPI VarCyFromI2(SHORT sIn, CY *pCyOut)
Definition: vartype.c:3435
HRESULT WINAPI VarDecFromI8(LONG64 llIn, DECIMAL *pDecOut)
Definition: vartype.c:4390
HRESULT WINAPI VarR4FromStr(const OLECHAR *strIn, LCID lcid, ULONG dwFlags, float *pFltOut)
Definition: vartype.c:2824
HRESULT WINAPI VarR8FromR4(FLOAT fltIn, double *pDblOut)
Definition: vartype.c:3090
HRESULT WINAPI VarCyFromI1(signed char cIn, CY *pCyOut)
Definition: vartype.c:3635
HRESULT WINAPI VarI4FromR4(FLOAT fltIn, LONG *piOut)
Definition: vartype.c:1522
HRESULT WINAPI VarBstrFromI1(signed char cIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:6982
HRESULT WINAPI VarDateFromDec(const DECIMAL *pdecIn, DATE *pdateOut)
Definition: vartype.c:8074
GLuint res
Definition: glext.h:9613
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:341
#define VARIANT_CALENDAR_THAI
Definition: oleauto.h:315
#define VAR_CALENDAR_GREGORIAN
Definition: oleauto.h:334
#define VARIANT_USE_NLS
Definition: oleauto.h:317
#define VARIANT_CALENDAR_HIJRI
Definition: oleauto.h:313
#define VAR_CALENDAR_THAI
Definition: oleauto.h:333
#define VARIANT_NOVALUEPROP
Definition: oleauto.h:310
#define VARIANT_NOUSEROVERRIDE
Definition: oleauto.h:312
#define LOCALE_USE_NLS
Definition: oleauto.h:338
#define VAR_CALENDAR_HIJRI
Definition: oleauto.h:329
#define V_DISPATCH(A)
Definition: oleauto.h:239
#define VARIANT_CALENDAR_GREGORIAN
Definition: oleauto.h:316
#define V_DATE(A)
Definition: oleauto.h:231
const GUID IID_IDispatch
#define DECIMAL_POS
Definition: variant.h:75
#define LOCALE_NOUSEROVERRIDE
Definition: winnls.h:19

Referenced by VariantChangeTypeEx().

◆ VARIANT_CoerceArray()

static HRESULT VARIANT_CoerceArray ( VARIANTARG pd,
VARIANTARG ps,
VARTYPE  vt 
)
inlinestatic

Definition at line 490 of file variant.c.

491{
492 if (vt == VT_BSTR && V_VT(ps) == (VT_ARRAY|VT_UI1))
493 return BstrFromVector(V_ARRAY(ps), &V_BSTR(pd));
494
495 if (V_VT(ps) == VT_BSTR && vt == (VT_ARRAY|VT_UI1))
496 return VectorFromBstr(V_BSTR(ps), &V_ARRAY(pd));
497
498 if (V_VT(ps) == vt)
499 return SafeArrayCopy(V_ARRAY(ps), &V_ARRAY(pd));
500
501 return DISP_E_TYPEMISMATCH;
502}
@ VT_ARRAY
Definition: compat.h:2341
HRESULT WINAPI SafeArrayCopy(SAFEARRAY *psa, SAFEARRAY **ppsaOut)
Definition: safearray.c:1379
HRESULT WINAPI VectorFromBstr(BSTR bstr, SAFEARRAY **ppsa)
Definition: safearray.c:1699
HRESULT WINAPI BstrFromVector(SAFEARRAY *psa, BSTR *pbstr)
Definition: safearray.c:1740

Referenced by VariantChangeTypeEx().

◆ VARIANT_CopyIRecordInfo()

static HRESULT VARIANT_CopyIRecordInfo ( VARIANT dest,
const VARIANT src 
)
static

Definition at line 670 of file variant.c.

671{
672 IRecordInfo *src_info = V_RECORDINFO(src);
673 HRESULT hr = S_OK;
674 ULONG size;
675
676 if (!src_info)
677 {
678 if (V_RECORD(src)) return E_INVALIDARG;
679 return S_OK;
680 }
681
682 hr = IRecordInfo_GetSize(src_info, &size);
683 if (FAILED(hr)) return hr;
684
685 /* Windows does not use RecordCreate() here, memory should be allocated in compatible way so RecordDestroy()
686 could free it later. */
688 if (!V_RECORD(dest)) return E_OUTOFMEMORY;
689 if (size)
690 memset(V_RECORD(dest), 0, size);
691
692 IRecordInfo_AddRef(V_RECORDINFO(dest) = src_info);
693 return IRecordInfo_RecordCopy(src_info, V_RECORD(src), V_RECORD(dest));
694}
HRESULT hr
Definition: delayimp.cpp:582
void *WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: malloc.c:381
GLenum src
Definition: glext.h:6340
GLsizeiptr size
Definition: glext.h:5919
static char * dest
Definition: rtl.c:149
#define memset(x, y, z)
Definition: compat.h:39
uint32_t ULONG
Definition: typedefs.h:59

Referenced by VariantCopy(), and VariantCopyInd().

◆ VARIANT_DataSize()

static size_t VARIANT_DataSize ( const VARIANT pv)
inlinestatic

Definition at line 767 of file variant.c.

768{
769 switch (V_TYPE(pv))
770 {
771 case VT_I1:
772 case VT_UI1: return sizeof(BYTE);
773 case VT_I2:
774 case VT_UI2: return sizeof(SHORT);
775 case VT_INT:
776 case VT_UINT:
777 case VT_I4:
778 case VT_UI4: return sizeof(LONG);
779 case VT_I8:
780 case VT_UI8: return sizeof(LONGLONG);
781 case VT_R4: return sizeof(float);
782 case VT_R8: return sizeof(double);
783 case VT_DATE: return sizeof(DATE);
784 case VT_BOOL: return sizeof(VARIANT_BOOL);
785 case VT_DISPATCH:
786 case VT_UNKNOWN:
787 case VT_BSTR: return sizeof(void*);
788 case VT_CY: return sizeof(CY);
789 case VT_ERROR: return sizeof(SCODE);
790 }
791 TRACE("Shouldn't be called for variant %s!\n", debugstr_variant(pv));
792 return 0;
793}
double DATE
Definition: compat.h:2253
union tagCY CY
LONG SCODE
Definition: compat.h:2252
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
int64_t LONGLONG
Definition: typedefs.h:68
unsigned char BYTE
Definition: xxhash.c:193

Referenced by VariantCopyInd().

◆ VARIANT_DateFromJulian()

static int VARIANT_DateFromJulian ( int  dateIn)
inlinestatic

Definition at line 1038 of file variant.c.

1039{
1040 int julianDays = dateIn;
1041
1042 julianDays -= 1757585; /* Convert to + days from 1 Jan 100 AD */
1043 julianDays += DATE_MIN; /* Convert to +/- days from 1 Jan 1899 AD */
1044 return julianDays;
1045}
#define DATE_MIN
Definition: variant.h:68

Referenced by VarDateFromUdateEx().

◆ VARIANT_DMYFromJulian()

static void VARIANT_DMYFromJulian ( int  jd,
USHORT year,
USHORT month,
USHORT day 
)
inlinestatic

Definition at line 1048 of file variant.c.

1049{
1050 int j, i, l, n;
1051
1052 l = jd + 68569;
1053 n = l * 4 / 146097;
1054 l -= (n * 146097 + 3) / 4;
1055 i = (4000 * (l + 1)) / 1461001;
1056 l += 31 - (i * 1461) / 4;
1057 j = (l * 80) / 2447;
1058 *day = l - (j * 2447) / 80;
1059 l = j / 11;
1060 *month = (j + 2) - (12 * l);
1061 *year = 100 * (n - 49) + i + l;
1062}
r l[0]
Definition: byte_order.h:168
static DOUBLE day(DOUBLE time)
Definition: date.c:75
static const WCHAR month[12][4]
Definition: session.c:2528
GLdouble n
Definition: glext.h:7729
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250

Referenced by VarUdateFromDate().

◆ VARIANT_FetchDispatchValue()

static HRESULT VARIANT_FetchDispatchValue ( LPVARIANT  pvDispatch,
LPVARIANT  pValue 
)
static

Definition at line 504 of file variant.c.

505{
506 DISPPARAMS params = { 0 };
508
509 if ((V_VT(pvDispatch) & VT_TYPEMASK) == VT_DISPATCH) {
510 if (NULL == V_DISPATCH(pvDispatch)) return DISP_E_TYPEMISMATCH;
511 hres = IDispatch_Invoke(V_DISPATCH(pvDispatch), DISPID_VALUE, &IID_NULL,
513 NULL, NULL);
514 } else {
516 }
517 return hres;
518}
PWCHAR pValue
GLenum const GLfloat * params
Definition: glext.h:5645
struct stdole::DISPPARAMS DISPPARAMS
#define DISPATCH_PROPERTYGET
Definition: oleauto.h:1007
#define IID_NULL
Definition: guiddef.h:98

Referenced by VarAbs(), VarAdd(), VarAnd(), VarCat(), VarDiv(), VarFix(), VarImp(), VarInt(), VarMod(), VarMul(), VarNeg(), VarNot(), VarOr(), VarPow(), VarRound(), VarSub(), and VarXor().

◆ VARIANT_GetLocalisedNumberChars()

static void VARIANT_GetLocalisedNumberChars ( VARIANT_NUMBER_CHARS lpChars,
LCID  lcid,
DWORD  dwFlags 
)
static

Definition at line 1508 of file variant.c.

1509{
1510 static const VARIANT_NUMBER_CHARS defaultChars = { '-','+','.',0,1,{'$',0},0,',' };
1512 WCHAR buff[4];
1513
1514 memcpy(lpChars, &defaultChars, sizeof(defaultChars));
1515 GET_NUMBER_TEXT(LOCALE_SNEGATIVESIGN, cNegativeSymbol);
1516 GET_NUMBER_TEXT(LOCALE_SPOSITIVESIGN, cPositiveSymbol);
1517 GET_NUMBER_TEXT(LOCALE_SDECIMAL, cDecimalPoint);
1518 GET_NUMBER_TEXT(LOCALE_STHOUSAND, cDigitSeparator);
1519 GET_NUMBER_TEXT(LOCALE_SMONDECIMALSEP, cCurrencyDecimalPoint);
1520 GET_NUMBER_TEXT(LOCALE_SMONTHOUSANDSEP, cCurrencyDigitSeparator);
1521
1522 if (!GetLocaleInfoW(lcid, lctype|LOCALE_SCURRENCY, lpChars->sCurrency, ARRAY_SIZE(lpChars->sCurrency)))
1523 {
1525 WARN("buffer too small for LOCALE_SCURRENCY\n");
1526 *lpChars->sCurrency = 0;
1527 }
1528 if (!*lpChars->sCurrency)
1529 wcscpy(lpChars->sCurrency, L"$");
1530 lpChars->sCurrencyLen = wcslen(lpChars->sCurrency);
1531 TRACE("lcid %#lx, sCurrency %lu %s\n", lcid, lpChars->sCurrencyLen, wine_dbgstr_w(lpChars->sCurrency));
1532}
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
#define L(x)
Definition: resources.c:13
#define wine_dbgstr_w
Definition: kernel32.h:34
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
short WCHAR
Definition: pedump.c:58
wcscpy
#define GET_NUMBER_TEXT(fld, name)
Definition: variant.c:1499
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LOCALE_SDECIMAL
Definition: winnls.h:52
#define LOCALE_SPOSITIVESIGN
Definition: winnls.h:127
#define LOCALE_SMONDECIMALSEP
Definition: winnls.h:61
#define LOCALE_SMONTHOUSANDSEP
Definition: winnls.h:62
#define LOCALE_STHOUSAND
Definition: winnls.h:53
#define LOCALE_SNEGATIVESIGN
Definition: winnls.h:128
DWORD LCTYPE
Definition: winnls.h:592
#define LOCALE_SCURRENCY
Definition: winnls.h:59

Referenced by VarParseNumFromStr().

◆ VARIANT_JulianFromDate()

static int VARIANT_JulianFromDate ( int  dateIn)
inlinestatic

Definition at line 1028 of file variant.c.

1029{
1030 int julianDays = dateIn;
1031
1032 julianDays -= DATE_MIN; /* Convert to + days from 1 Jan 100 AD */
1033 julianDays += 1757585; /* Convert to + days from 23 Nov 4713 BC (Julian) */
1034 return julianDays;
1035}

Referenced by VarUdateFromDate().

◆ VARIANT_JulianFromDMY()

static double VARIANT_JulianFromDMY ( USHORT  year,
USHORT  month,
USHORT  day 
)
inlinestatic

Definition at line 1065 of file variant.c.

1066{
1067 int m12 = (month - 14) / 12;
1068
1069 return ((1461 * (year + 4800 + m12)) / 4 + (367 * (month - 2 - 12 * m12)) / 12 -
1070 (3 * ((year + 4900 + m12) / 100)) / 4 + day - 32075);
1071}
#define m12

Referenced by VarDateFromUdateEx().

◆ VARIANT_RollUdate()

static HRESULT VARIANT_RollUdate ( UDATE lpUd)
static

Definition at line 1085 of file variant.c.

1086{
1087 static const BYTE days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
1088 short iYear, iMonth, iDay, iHour, iMinute, iSecond;
1089
1090 /* interpret values signed */
1091 iYear = lpUd->st.wYear;
1092 iMonth = lpUd->st.wMonth;
1093 iDay = lpUd->st.wDay;
1094 iHour = lpUd->st.wHour;
1095 iMinute = lpUd->st.wMinute;
1096 iSecond = lpUd->st.wSecond;
1097
1098 TRACE("Raw date: %d/%d/%d %d:%d:%d\n", iDay, iMonth,
1099 iYear, iHour, iMinute, iSecond);
1100
1101 if (iYear > 9999 || iYear < -9999)
1102 return E_INVALIDARG; /* Invalid value */
1103 /* Years 0 to 49 are treated as 2000 + year, see also VARIANT_MakeDate() */
1104 if (0 <= iYear && iYear <= 49)
1105 iYear += 2000;
1106 /* Remaining years 50 to 99 are treated as 1900 + year */
1107 else if (50 <= iYear && iYear <= 99)
1108 iYear += 1900;
1109
1110 iMinute += iSecond / 60;
1111 iSecond = iSecond % 60;
1112 iHour += iMinute / 60;
1113 iMinute = iMinute % 60;
1114 iDay += iHour / 24;
1115 iHour = iHour % 24;
1116 iYear += iMonth / 12;
1117 iMonth = iMonth % 12;
1118 if (iMonth<=0) {iMonth+=12; iYear--;}
1119 while (iDay > days[iMonth])
1120 {
1121 if (iMonth == 2 && IsLeapYear(iYear))
1122 iDay -= 29;
1123 else
1124 iDay -= days[iMonth];
1125 iMonth++;
1126 iYear += iMonth / 12;
1127 iMonth = iMonth % 12;
1128 }
1129 while (iDay <= 0)
1130 {
1131 iMonth--;
1132 if (iMonth<=0) {iMonth+=12; iYear--;}
1133 if (iMonth == 2 && IsLeapYear(iYear))
1134 iDay += 29;
1135 else
1136 iDay += days[iMonth];
1137 }
1138
1139 if (iSecond<0){iSecond+=60; iMinute--;}
1140 if (iMinute<0){iMinute+=60; iHour--;}
1141 if (iHour<0) {iHour+=24; iDay--;}
1142 if (iYear<=0) iYear+=2000;
1143
1144 lpUd->st.wYear = iYear;
1145 lpUd->st.wMonth = iMonth;
1146 lpUd->st.wDay = iDay;
1147 lpUd->st.wHour = iHour;
1148 lpUd->st.wMinute = iMinute;
1149 lpUd->st.wSecond = iSecond;
1150
1151 TRACE("Rolled date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth,
1152 lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond);
1153 return S_OK;
1154}
#define IsLeapYear(y)
Definition: variant.c:1025

Referenced by VarDateFromUdateEx(), and VarUdateFromDate().

◆ VARIANT_ValidateType()

static HRESULT VARIANT_ValidateType ( VARTYPE  vt)
inlinestatic

Definition at line 523 of file variant.c.

524{
525 VARTYPE vtExtra = vt & VT_EXTRA_TYPE;
526
527 vt &= VT_TYPEMASK;
528
529 if (!(vtExtra & (VT_VECTOR|VT_RESERVED)))
530 {
531 if (vt < VT_VOID || vt == VT_RECORD || vt == VT_CLSID)
532 {
533 if ((vtExtra & (VT_BYREF|VT_ARRAY)) && vt <= VT_NULL)
534 return DISP_E_BADVARTYPE;
535 if (vt != (VARTYPE)15)
536 return S_OK;
537 }
538 }
539 return DISP_E_BADVARTYPE;
540}
@ VT_VECTOR
Definition: compat.h:2340
#define VT_EXTRA_TYPE
Definition: variant.h:31

Referenced by VarFix(), VARIANT_ClearInd(), VariantChangeTypeEx(), VariantClear(), VariantCopy(), VarNeg(), and VarNot().

◆ VariantChangeType()

HRESULT WINAPI DECLSPEC_HOTPATCH VariantChangeType ( VARIANTARG pvargDest,
const VARIANTARG pvargSrc,
USHORT  wFlags,
VARTYPE  vt 
)

◆ VariantChangeTypeEx()

HRESULT WINAPI VariantChangeTypeEx ( VARIANTARG pvargDest,
const VARIANTARG pvargSrc,
LCID  lcid,
USHORT  wFlags,
VARTYPE  vt 
)

Definition at line 965 of file variant.c.

967{
968 HRESULT res = S_OK;
969
970 TRACE("%s, %s, %#lx, 0x%04x, %s.\n", debugstr_variant(pvargDest),
971 debugstr_variant(pvargSrc), lcid, wFlags, debugstr_vt(vt));
972
973 if (vt == VT_CLSID)
975 else
976 {
977 res = VARIANT_ValidateType(V_VT(pvargSrc));
978
979 if (SUCCEEDED(res))
980 {
982
983 if (SUCCEEDED(res))
984 {
985 VARIANTARG vTmp, vSrcDeref;
986
987 if(V_ISBYREF(pvargSrc) && !V_BYREF(pvargSrc))
989 else
990 {
991 V_VT(&vTmp) = VT_EMPTY;
992 V_VT(&vSrcDeref) = VT_EMPTY;
993 VariantClear(&vTmp);
994 VariantClear(&vSrcDeref);
995 }
996
997 if (SUCCEEDED(res))
998 {
999 res = VariantCopyInd(&vSrcDeref, pvargSrc);
1000 if (SUCCEEDED(res))
1001 {
1002 if (V_ISARRAY(&vSrcDeref) || (vt & VT_ARRAY))
1003 res = VARIANT_CoerceArray(&vTmp, &vSrcDeref, vt);
1004 else
1005 res = VARIANT_Coerce(&vTmp, lcid, wFlags, &vSrcDeref, vt);
1006
1007 if (SUCCEEDED(res)) {
1008 V_VT(&vTmp) = vt;
1009 res = VariantCopy(pvargDest, &vTmp);
1010 }
1011 VariantClear(&vTmp);
1012 VariantClear(&vSrcDeref);
1013 }
1014 }
1015 }
1016 }
1017 }
1018
1019 TRACE("returning %#lx, %s\n", res, debugstr_variant(pvargDest));
1020 return res;
1021}
#define V_BYREF(A)
Definition: oleauto.h:228
static HRESULT VARIANT_Coerce(VARIANTARG *pd, LCID lcid, USHORT wFlags, VARIANTARG *ps, VARTYPE vt)
Definition: variant.c:44
HRESULT WINAPI VariantCopyInd(VARIANT *pvargDest, const VARIANTARG *pvargSrc)
Definition: variant.c:823
static HRESULT VARIANT_CoerceArray(VARIANTARG *pd, VARIANTARG *ps, VARTYPE vt)
Definition: variant.c:490

Referenced by _VarChangeTypeExWrap(), document_write(), double_to_string(), invoke(), OLEFontImpl_Invoke(), OLEPictureImpl_Invoke(), RegistryPropertyBag_IPropertyBag_Read(), test_ChangeType_keep_dst(), test_EmptyChangeTypeEx(), test_ErrorChangeTypeEx(), test_IDispatchChangeTypeEx(), test_IUnknownChangeTypeEx(), test_nodeTypedValue(), test_NullByRef(), test_NullChangeTypeEx(), test_safearray(), test_SafeArrayChangeTypeEx(), test_UintChangeTypeEx(), test_VarDateChangeTypeEx(), test_VarUI1FromDisp(), VarCat(), VarCmp(), VarFormatCurrency(), VarFormatFromTokens(), VarFormatNumber(), VarFormatPercent(), VARIANT_FormatDate(), VARIANT_FormatNumber(), VARIANT_FormatString(), variant_from_dt(), VARIANT_FromDisp(), and VariantChangeType().

◆ VariantClear()

HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear ( VARIANTARG pVarg)

Definition at line 626 of file variant.c.

627{
629
630 TRACE("(%s)\n", debugstr_variant(pVarg));
631
633
634 if (SUCCEEDED(hres))
635 {
636 if (!V_ISBYREF(pVarg))
637 {
638 if (V_ISARRAY(pVarg) || V_VT(pVarg) == VT_SAFEARRAY)
639 {
640 hres = SafeArrayDestroy(V_ARRAY(pVarg));
641 }
642 else if (V_VT(pVarg) == VT_BSTR)
643 {
644 SysFreeString(V_BSTR(pVarg));
645 }
646 else if (V_VT(pVarg) == VT_RECORD)
647 {
648 IRecordInfo *rec_info = V_RECORDINFO(pVarg);
649 if (rec_info)
650 {
651 IRecordInfo_RecordClear(rec_info, V_RECORD(pVarg));
652 IRecordInfo_Release(rec_info);
653 }
654 }
655 else if (V_VT(pVarg) == VT_DISPATCH ||
656 V_VT(pVarg) == VT_UNKNOWN)
657 {
658 if (V_UNKNOWN(pVarg))
659 IUnknown_Release(V_UNKNOWN(pVarg));
660 }
661 }
662 V_VT(pVarg) = VT_EMPTY;
663 }
664 return hres;
665}

Referenced by _check_default_props(), _check_property(), _check_set_props(), _create_img_elem(), _create_option_elem(), CRegPropertyBag::_ReadString(), _set_framebase_marginheight(), _set_framebase_marginwidth(), _set_iframe_height(), _set_iframe_width(), _set_props(), _test_border_styles(), _test_clone(), _test_disp_value(), _test_elem_attr(), _test_framebase_marginheight(), _test_framebase_marginwidth(), _test_iframe_height(), _test_iframe_width(), _test_node_get_value_str(), _test_node_put_value_str(), _test_readyState(), _test_table_cell_padding(), _test_table_cell_spacing(), _test_tr_possess(), _unset_props(), AccessibleObjectFromPoint(), add_keyitem_pair(), assign_value(), AutomationObject_Invoke(), AVICompressorPropertyBag_Load(), base_hwnd_provider_GetPropertyValue(), build_directshowfilters_tree(), builtin_propput(), call_event_handlers(), call_script(), call_timer_disp(), check_uia_prop_val(), clean_props(), SEALED_::CleanupEventArgumentsCallback(), ClearCustData(), Client_EnumVARIANT_Next(), create_enumerator(), create_signature_columns_and_data(), create_test_element_from_hwnd(), create_uia_element_from_cache_req(), create_xmlhttprequest(), CreateFolderFromNameSpace(), database_invoke(), disp_call(), disp_call_value_with_caller(), disp_propget(), disp_propput(), DispatchEx_InvokeEx(), dispex_unlink(), document_write(), domattr_get_nodeTypedValue(), domdoc_setProperty(), domelem_put_nodeTypedValue(), domelem_setAttribute(), domelem_setAttributeNode(), element_get_dt(), enum_find_filter(), enumvar_get_next_item(), exec_assoc_view(), exec_query(), fill_filter_container(), fill_processor_information(), FilterGraph2_Connect(), FilterGraph2_Render(), FilterMapper3_EnumMatchingFilters(), FilterMapper_EnumMatchingFilters(), free_keyitem_pair(), free_property_information(), free_request(), get_attribute_value(), get_diskdrivetodiskpartition_pairs(), get_doc_ready_state(), get_element_variant_from_node_variant(), get_fixed_drive(), get_hwnd_from_provider(), get_logicaldisktopartition_pairs(), get_node_provider_description_string(), get_owner(), CFolderItem::get_Type(), GetFilterInfo(), GetShellFolder2ItemDetailsExToBuffer(), GetSplitter(), Global_Abs(), Global_CBool(), Global_CByte(), Global_CCur(), Global_Fix(), Global_Int(), Global_InvokeEx(), handle_xml_load(), HostConstructor_call(), HostFunction_call(), HostObject_prop_get(), HostObject_prop_put(), HTMLDocument_execCommand(), HTMLElement3_put_disabled(), HTMLElement_populate_props(), HTMLElement_put_title(), httprequest_get_responseBody(), IDispatch_Invoke_Proxy(), IDispatch_Invoke_Stub(), iframe_onreadystatechange(), Installer_ProductInfo(), Installer_ProductState(), Installer_RegistryValue(), Installer_RegistryValueE(), Installer_RegistryValueI(), Installer_RegistryValueW(), Installer_VersionGet(), InstallerImpl_InstallProduct(), InstallerImpl_OpenDatabase(), InstallerImpl_OpenPackage(), InstallerImpl_OpenProduct(), InstallerImpl_ProductInfo(), InstallerImpl_ProductState(), InstallerImpl_RegistryValue(), InstallerImpl_RelatedProducts(), InstallerImpl_SummaryInformation(), interp_enumnext(), interp_incc(), interp_is(), interp_newenum(), interp_redim(), interp_redim_preserve(), interp_retval(), interp_vcall(), interp_vcallv(), invoke(), invoke_builtin_function(), invoke_builtin_prop(), invoke_vbdisp(), IPropertyBag_Read_Stub(), IRecordInfoImpl_GetField(), IRecordInfoImpl_GetFieldNoCopy(), ITypeInfo2_fnGetCustData(), ITypeInfo_fnInvoke(), ITypeInfoImpl_Destroy(), jsval_release(), list_free(), MatchCollectionEnum_Next(), msaa_acc_get_focus(), navigate_javascript_proc(), navigate_url(), node_put_value(), node_put_value_escaped(), notif_enabled(), objectset_ItemIndex(), OleCommandTarget_Exec(), OLEFont_SendNotify(), OLEFontImpl_Invoke(), OLEFontImpl_IPersistPropertyBag_Load(), OLEPictureImpl_Invoke(), prepare_for_binding(), process_get_owner(), PropertyBag_Release(), propertyset_Item(), proxy_event_sink_clear(), query_prop(), QueryOperatingSystemInfo(), QueryProcessorInfo(), read_property_names(), Record_FieldCountGet(), Record_IntegerDataGet(), record_invoke(), Record_StringDataGet(), refresh_document(), reg_create_key(), reg_enum_key(), reg_enum_values(), reg_get_stringvalue(), register_avicap_devices(), register_codec(), register_dsound_devices(), register_midiout_devices(), register_vfw_codecs(), register_wavein_devices(), register_waveout_devices(), release_dispex(), release_dynamic_var(), release_exec(), release_val(), remove_attribute(), remove_event_handler(), reset_request(), run_script(), SAFEARRAY_DestroyData(), security_get_sd(), service_pause_service(), service_resume_service(), service_start_service(), service_stop_service(), Session_DoAction(), Session_EvaluateCondition(), Session_FeatureCurrentState(), Session_FeatureRequestStateGet(), session_invoke(), Session_LanguageGet(), Session_ModeGet(), Session_PropertyGet(), set_status_text(), CCompartment::SetValue(), SHPropertyBag_OnIniFile(), SHPropertyBag_OnMemory(), SHPropertyBag_OnRegKey(), stack_pop_disp(), stack_popn(), stack_push(), StringList_Count(), StringList_Item(), summaryinfo_invoke(), SummaryInfo_PropertyCountGet(), super_navigate(), test_ADsBuildVarArrayStr(), test_attr(), test_attr_collection(), test_attr_collection_disp(), test_body_funs(), test_body_style(), test_BstrCopy(), test_cache_req_sa_(), test_case_sens(), test_change_type(), test_change_types(), test_child_col_disp(), test_cloneNode(), test_codec(), test_com_event_data_(), test_container_properties(), test_create(), test_createProcessingInstruction(), test_CreateTypeLib(), test_CUIAutomation_cache_request_iface(), test_CUIAutomation_condition_ifaces(), test_current_style(), test_default_body(), test_default_client_accessible_object(), test_default_clientside_providers(), test_default_properties(), test_default_value(), test_destructors(), test_devenum(), test_directshow_filter(), test_dispatch(), test_DispCallFunc(), test_DispGetParam(), test_dmo(), test_dom_implementation(), test_domdoc(), test_domnode(), test_DriveCollection(), test_dsound(), test_dump_typelib(), test_Element_cache_methods(), test_Element_Find(), test_Element_GetPropertyValue(), test_EmptyChangeTypeEx(), test_exec_fontname(), test_exec_script(), test_FileCollection(), test_focus(), test_FolderCollection(), test_font_events_disp(), test_frames_collection(), test_func(), test_get_childNodes(), test_get_dataType(), test_get_focused_elem_(), test_get_namespaces(), test_get_set_attr(), test_get_xml(), test_getAttribute(), test_GetRootElement(), test_global_id(), test_hash_value(), test_IDispatchClear(), test_imgload(), test_InitPropVariantFromBuffer(), test_InitPropVariantFromGUIDAsString(), test_Installer_Products(), test_Installer_RegistryValue(), test_interfaces(), test_invokeex(), test_isexpression(), test_items(), test_ITextDocument_Open(), test_IUIAutomationEventHandler(), test_IUnknownClear(), test_IWinHttpRequest(), test_IXMLDOMDocument2(), test_Keys(), test_legacy_filter(), test_load(), test_locator(), test_marshal_variant(), test_members(), test_midiout(), test_mxnamespacemanager(), test_mxwriter_cdata(), test_mxwriter_characters(), test_mxwriter_comment(), test_mxwriter_dtd(), test_mxwriter_encoding(), test_mxwriter_flush(), test_mxwriter_ignorablespaces(), test_mxwriter_indent(), test_mxwriter_pi(), test_mxwriter_properties(), test_mxwriter_startenddocument(), test_mxwriter_startendelement(), test_mxwriter_startendelement_batch(), test_mxwriter_startendelement_batch2(), test_mxwriter_stream(), test_named_items(), test_namedmap_newenum(), test_namespace(), test_node_hwnd_provider_(), test_node_hwnd_provider_navigation_(), test_nodeTypedValue(), test_nodeValue(), test_NullByRef(), test_number_localization(), test_object_elem(), test_OleLoadPicturePath(), test_onclick(), test_ParseDisplayName(), test_ParseName(), test_procedures(), test_propertybag_read(), test_propertybag_write(), test_propputref(), test_PropVariantToGUID(), test_PropVariantToVariant(), test_put_nodeTypedValue(), test_put_nodeValue(), test_RegExp(), test_registry(), test_safearray(), test_SafeArrayChangeTypeEx(), test_SafeArrayClear(), test_save(), test_saxreader(), test_saxreader_properties(), test_schema_refs(), test_script_dispatch(), test_script_exprs(), test_script_run(), test_selection(), test_set_csstext(), test_specific_encoder_properties(), test_StaticWidget(), test_StdRegProv(), test_style2(), test_style3(), test_style4(), test_style5(), test_stylesheets(), test_SummaryInfo(), test_SystemSecurity(), test_table_elem(), test_td_elem(), test_tr_elem(), test_type_info(), test_TypeInfo(), test_typelibmarshal(), test_uia_element_arr_(), test_uia_prov_from_acc_properties(), test_UiaAddEvent(), test_UiaFind(), test_UiaGetPropertyValue(), test_UiaGetRootNode(), test_UiaGetRuntimeId(), test_UiaGetUpdatedCache(), test_UiaHostProviderFromHwnd(), test_UiaHUiaNodeFromVariant(), test_UiaNavigate(), test_UiaNodeFromHandle(), test_UiaNodeFromHandle_client_proc(), test_UiaNodeFromProvider(), test_UiaProviderFromIAccessible(), test_UiaRegisterProviderCallback(), test_var_call1(), test_var_call2(), test_VarAdd(), test_VarCat(), test_VarDateChangeTypeEx(), test_VarFormatCurrency(), test_VarFormatFromTokens(), test_VariantClear(), test_VariantCopy(), test_VariantCopyInd(), test_VariantToPropVariant(), test_VariantToString(), test_VariantToStringWithDefault(), test_Verbs(), test_vfw(), test_wavein(), test_waveout(), test_Win32_Baseboard(), test_Win32_Bios(), test_Win32_ComputerSystem(), test_Win32_OperatingSystem(), test_Win32_PnPEntity(), test_Win32_Printer(), test_Win32_Process(), test_Win32_Service(), test_Win32_SystemEnclosure(), test_Win32_VideoController(), test_wshshell(), test_XDR_datatypes(), test_XDR_schemas(), test_xmlelem(), test_xmlelem_collection(), test_XMLHTTP(), test_xmlhttprequest(), test_xmlTypes(), test_XPath(), test_xsltemplate(), TLB_AllocAndInitVarDesc(), TLB_FreeCustData(), TLB_FreeElemDesc(), TLB_FreeVarDesc(), TLB_set_custdata(), typeinfo_release_funcdesc(), uia_com_focus_win_event_callback(), uia_com_focus_win_event_handler(), uia_condition_destroy(), uia_element_get_CurrentBoundingRectangle(), uia_element_get_CurrentControlType(), uia_element_get_CurrentName(), uia_element_Release(), uia_nested_node_provider_create_node_from_prov(), uia_nested_node_provider_get_focus(), uia_nested_node_provider_get_prop_val(), uia_nested_node_provider_navigate(), uia_node_from_handle_test_thread(), uia_node_ptr_to_unk_safearray(), uia_property_condition_check(), uia_property_condition_Release(), uia_provider_get_elem_prop_val(), uia_provider_get_focus(), uia_provider_get_special_prop_val(), UiaFind(), UiaGetRuntimeId(), UiaGetUpdatedCache(), update_readystate(), validate_regex_document(), VarAbs(), VarAdd(), VarAnd(), VarCat(), VarCmp(), VarDiv(), VarFix(), VARIANT_ClearInd(), VARIANT_Coerce(), VARIANT_FormatNumber(), VARIANT_FormatString(), variant_from_dt(), VARIANT_FromDisp(), VARIANT_UserFree(), VARIANT_UserUnmarshal(), VariantChangeType_ChangeType(), VariantChangeTypeEx(), VariantClearAndInvalidate(), VariantClearLazy(), VariantCopy(), VariantCopyInd(), VarIdiv(), VarImp(), VarInt(), VarMod(), VarMul(), VarNeg(), VarNot(), VarOr(), VarPow(), VarRound(), VarSub(), VarXor(), VBArray_getItem(), view_invoke(), Widget_variant(), WindowFromAccessibleObject(), winhttp_request_Send(), CRegPropertyBag::Write(), CIniPropertyBag::Write(), write_filter_data(), WshShell3_Popup(), WshShell3_RegWrite(), xmldoc_encoding(), xslprocessor_transform(), and CCompartment::~CCompartment().

◆ VariantCopy()

HRESULT WINAPI VariantCopy ( VARIANTARG pvargDest,
const VARIANTARG pvargSrc 
)

Definition at line 724 of file variant.c.

725{
726 HRESULT hres = S_OK;
727
728 TRACE("(%s,%s)\n", debugstr_variant(pvargDest), debugstr_variant(pvargSrc));
729
730 if (V_TYPE(pvargSrc) == VT_CLSID || /* VT_CLSID is a special case */
731 FAILED(VARIANT_ValidateType(V_VT(pvargSrc))))
732 return DISP_E_BADVARTYPE;
733
734 if (pvargSrc != pvargDest &&
735 SUCCEEDED(hres = VariantClear(pvargDest)))
736 {
737 *pvargDest = *pvargSrc; /* Shallow copy the value */
738
739 if (!V_ISBYREF(pvargSrc))
740 {
741 switch (V_VT(pvargSrc))
742 {
743 case VT_BSTR:
744 V_BSTR(pvargDest) = SysAllocStringByteLen((char*)V_BSTR(pvargSrc), SysStringByteLen(V_BSTR(pvargSrc)));
745 if (!V_BSTR(pvargDest))
747 break;
748 case VT_RECORD:
749 hres = VARIANT_CopyIRecordInfo(pvargDest, pvargSrc);
750 break;
751 case VT_DISPATCH:
752 case VT_UNKNOWN:
753 V_UNKNOWN(pvargDest) = V_UNKNOWN(pvargSrc);
754 if (V_UNKNOWN(pvargSrc))
755 IUnknown_AddRef(V_UNKNOWN(pvargSrc));
756 break;
757 default:
758 if (V_ISARRAY(pvargSrc))
759 hres = SafeArrayCopy(V_ARRAY(pvargSrc), &V_ARRAY(pvargDest));
760 }
761 }
762 }
763 return hres;
764}
UINT WINAPI SysStringByteLen(BSTR str)
Definition: oleaut.c:217
BSTR WINAPI DECLSPEC_HOTPATCH SysAllocStringByteLen(LPCSTR str, UINT len)
Definition: oleaut.c:430
static HRESULT VARIANT_CopyIRecordInfo(VARIANT *dest, const VARIANT *src)
Definition: variant.c:670

Referenced by create_uia_property_condition_iface(), dict_enum_Next(), dictionary_get_Item(), dictionary_Items(), dictionary_Keys(), function_invoke(), get_event_handler(), HTMLEventObj_get_returnValue(), HTMLStyle3_get_zoom(), IDispatch_Invoke_Proxy(), IDispatch_Invoke_Stub(), IDxDiagContainerImpl_GetProp(), Installer_RegistryValue(), interp_deref(), interp_numval(), interp_retval(), interp_stack(), interp_val(), ITypeInfo2_fnGetCustData(), ITypeInfo2_fnGetFuncCustData(), ITypeInfo2_fnGetImplTypeCustData(), ITypeInfo2_fnGetParamCustData(), ITypeInfo2_fnGetVarCustData(), ITypeInfo_fnInvoke(), ITypeLib2_fnGetCustData(), jsval_to_variant(), jsval_variant(), list_invoke(), ListEnumerator_Next(), PropertyBag_Read(), PropertyBag_Write(), ProxyEventSink_AddAutomationPropertyChangedEvent(), CMemPropertyBag::Read(), SAFEARRAY_CopyData(), safearray_iter_IEnumVARIANT_Next(), SafeArrayGetElement(), SafeArrayPutElement(), stack_assume_val(), test_BstrCopy(), test_IDispatchCopy(), test_IUnknownCopy(), test_SafeArrayCopy(), test_VariantCopy(), TLB_AllocAndInitVarDesc(), TLB_copy_all_custdata(), TLB_CopyElemDesc(), TLB_set_custdata(), uia_condition_clone(), uia_element_GetCachedPropertyValueEx(), uia_property_condition_get_PropertyValue(), VarAdd(), VarAnd(), VARIANT_Coerce(), variant_copy(), VariantChangeTypeEx(), VariantCopyInd(), VarImp(), VarMul(), VarOr(), and VarXor().

◆ VariantCopyInd()

HRESULT WINAPI VariantCopyInd ( VARIANT pvargDest,
const VARIANTARG pvargSrc 
)

Definition at line 823 of file variant.c.

824{
825 const VARIANTARG *pSrc = pvargSrc;
826 VARIANTARG vTmp;
827 VARTYPE vt;
828 HRESULT hres = S_OK;
829
830 TRACE("(%s,%s)\n", debugstr_variant(pvargDest), debugstr_variant(pvargSrc));
831
832 if (!V_ISBYREF(pvargSrc))
833 return VariantCopy(pvargDest, pvargSrc);
834
835 /* Argument checking is more lax than VariantCopy()... */
836 vt = V_TYPE(pvargSrc);
837 if (V_ISARRAY(pvargSrc) || (V_VT(pvargSrc) == (VT_RECORD|VT_BYREF)) ||
838 (vt > VT_NULL && vt != (VARTYPE)15 && vt < VT_VOID &&
839 !(V_VT(pvargSrc) & (VT_VECTOR|VT_RESERVED))))
840 {
841 /* OK */
842 }
843 else
844 return E_INVALIDARG; /* ...And the return value for invalid types differs too */
845
846 if (pvargSrc == pvargDest)
847 {
848 /* In place copy. Use a shallow copy of pvargSrc & init pvargDest.
849 * This avoids an expensive VariantCopy() call - e.g. SafeArrayCopy().
850 */
851 vTmp = *pvargSrc;
852 pSrc = &vTmp;
853 V_VT(pvargDest) = VT_EMPTY;
854 }
855 else
856 {
857 /* Copy into another variant. Free the variant in pvargDest */
858 if (FAILED(hres = VariantClear(pvargDest)))
859 {
860 TRACE("VariantClear() of destination failed\n");
861 return hres;
862 }
863 }
864
865 if (V_ISARRAY(pSrc))
866 {
867 /* Native doesn't check that *V_ARRAYREF(pSrc) is valid */
868 hres = SafeArrayCopy(*V_ARRAYREF(pSrc), &V_ARRAY(pvargDest));
869 }
870 else if (V_VT(pSrc) == (VT_BSTR|VT_BYREF))
871 {
872 /* Native doesn't check that *V_BSTRREF(pSrc) is valid */
873 V_BSTR(pvargDest) = SysAllocStringByteLen((char*)*V_BSTRREF(pSrc), SysStringByteLen(*V_BSTRREF(pSrc)));
874 }
875 else if (V_VT(pSrc) == (VT_RECORD|VT_BYREF))
876 {
877 hres = VARIANT_CopyIRecordInfo(pvargDest, pvargSrc);
878 }
879 else if (V_VT(pSrc) == (VT_DISPATCH|VT_BYREF) ||
880 V_VT(pSrc) == (VT_UNKNOWN|VT_BYREF))
881 {
882 /* Native doesn't check that *V_UNKNOWNREF(pSrc) is valid */
883 V_UNKNOWN(pvargDest) = *V_UNKNOWNREF(pSrc);
884 if (*V_UNKNOWNREF(pSrc))
885 IUnknown_AddRef(*V_UNKNOWNREF(pSrc));
886 }
887 else if (V_VT(pSrc) == (VT_VARIANT|VT_BYREF))
888 {
889 /* Native doesn't check that *V_VARIANTREF(pSrc) is valid */
890 if (V_VT(V_VARIANTREF(pSrc)) == (VT_VARIANT|VT_BYREF))
891 hres = E_INVALIDARG; /* Don't dereference more than one level */
892 else
893 hres = VariantCopyInd(pvargDest, V_VARIANTREF(pSrc));
894
895 /* Use the dereferenced variants type value, not VT_VARIANT */
896 goto VariantCopyInd_Return;
897 }
898 else if (V_VT(pSrc) == (VT_DECIMAL|VT_BYREF))
899 {
900 memcpy(&V_DECIMAL(pvargDest).scale, &V_DECIMALREF(pSrc)->scale,
901 sizeof(DECIMAL) - sizeof(USHORT));
902 }
903 else
904 {
905 /* Copy the pointed to data into this variant */
906 memcpy(&V_BYREF(pvargDest), V_BYREF(pSrc), VARIANT_DataSize(pSrc));
907 }
908
909 V_VT(pvargDest) = V_VT(pSrc) & ~VT_BYREF;
910
911VariantCopyInd_Return:
912
913 if (pSrc != pvargSrc)
914 VariantClear(&vTmp);
915
916 TRACE("returning %#lx, %s\n", hres, debugstr_variant(pvargDest));
917 return hres;
918}
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9032
#define V_DECIMALREF(A)
Definition: oleauto.h:238
unsigned short USHORT
Definition: pedump.c:61
static size_t VARIANT_DataSize(const VARIANT *pv)
Definition: variant.c:767

Referenced by add_keyitem_pair(), assign_value(), dictionary_put_Item(), DispGetParam_CopyOnly(), exec_script(), Global_Array(), invoke_variant_prop(), CFolderItems::Item(), ITypeInfo_fnInvoke(), SummaryInfo_PropertyPut(), test_IDispatchCopy(), test_IUnknownCopy(), test_VariantCopyInd(), VarFormatCurrency(), VarFormatNumber(), VarFormatPercent(), VariantChangeTypeEx(), VariantCopyInd(), and winhttp_request_Send().

◆ VariantInit()

void WINAPI VariantInit ( VARIANTARG pVarg)

Definition at line 547 of file variant.c.

548{
549 TRACE("(%p)\n", pVarg);
550
551 memset(pVarg, 0, sizeof(*pVarg));
552}

Referenced by _call_change_type(), _check_default_props(), _check_property(), _check_set_props(), _set_props(), _test_clone(), _test_elem_attr(), _test_readyState(), _unset_props(), Accessible_accNavigate(), Accessible_get_accFocus(), AccessibleChildren(), AccessibleObjectFromEvent(), add_keyitem_pair(), ADsBuildVarArrayStr(), AutomationObject_Invoke(), base_hwnd_provider_GetPropertyValue(), call_docview_84(), call_explorer_69(), CCompartment::CCompartment(), ATL::CComVariant::CComVariant(), ClientSideProvider_GetPropertyValue(), create_control_view_condition_iface(), create_enumerator(), create_node_from_node_provider(), create_uia_element_from_cache_req(), create_xmlhttprequest(), database_invoke(), Database_OpenView(), Database_SummaryInformation(), DatabaseImpl_LastErrorRecord(), DEVENUM_IMediaCatMoniker_BindToObject(), dictionary_get_Item(), dictionary_put_Key(), domelem_put_nodeTypedValue(), domelem_setAttribute(), element_get_dt(), encode_frame_wic(), enum_find_filter(), enumvar_get_next_item(), fill_filter_container(), FilterMapper3_EnumMatchingFilters(), FilterMapper_EnumMatchingFilters(), get_client_disp_property(), get_dynamic_prop(), get_focus_from_node_provider(), get_focused_uia_node(), get_hwnd_from_provider(), get_navigate_from_node_provider(), get_node_provider_description_string(), get_node_type(), get_prop_val_from_node(), get_prop_val_from_node_provider(), get_variant_for_elprov_node(), GetFilterInfo(), CCompartment::GetValue(), httprequest_open(), hwnd_host_provider_GetPropertyValue(), IDispatch_Invoke_Proxy(), IDispatch_Invoke_Stub(), IDxDiagContainerImpl_GetProp(), initialize_request(), InitVariantFromBuffer(), InitVariantFromFileTime(), Installer_CreateRecord(), Installer_InstallProduct(), Installer_OpenDatabase(), Installer_OpenPackage(), Installer_ProductInfo(), Installer_ProductState(), Installer_RegistryValue(), Installer_RegistryValueE(), Installer_RegistryValueI(), Installer_RegistryValueW(), Installer_RelatedProducts(), Installer_SummaryInformation(), Installer_UILevelPut(), InstallerImpl_CreateRecord(), InstallerImpl_EnableLog(), InstallerImpl_Environment(), InstallerImpl_FileAttributes(), InstallerImpl_FileSize(), InstallerImpl_FileVersion(), InstallerImpl_InstallProduct(), InstallerImpl_LastErrorRecord(), InstallerImpl_OpenDatabase(), InstallerImpl_OpenPackage(), InstallerImpl_OpenProduct(), InstallerImpl_ProductInfo(), InstallerImpl_ProductState(), InstallerImpl_RegistryValue(), InstallerImpl_RelatedProducts(), InstallerImpl_SummaryInformation(), InstallerImpl_UILevel(), invoke(), ITypeInfo2_fnGetCustData(), ITypeInfo2_fnGetFuncCustData(), ITypeInfo2_fnGetImplTypeCustData(), ITypeInfo2_fnGetParamCustData(), ITypeInfo2_fnGetVarCustData(), ITypeInfo_fnInvoke(), ITypeLib2_fnGetCustData(), list_invoke(), ListEnumerator_Next(), load_manifest(), msaa_acc_get_focus(), msaa_acc_prop_match(), msaa_acc_provider_get_Role(), msaa_check_acc_state_hres(), msaa_provider_GetPropertyValue(), navigate_uia_node(), node_append_child(), node_put_value(), node_put_value_escaped(), OLEFont_SendNotify(), OLEFontImpl_Invoke(), OLEFontImpl_IPersistPropertyBag_Load(), OLEPictureImpl_Invoke(), parse_elem_text(), process_get_owner(), PropertyBag_Read(), PropVariantToVariant(), ProviderSimple_GetPropertyValue(), CMemPropertyBag::Read(), CRegPropertyBag::Read(), CIniPropertyBag::Read(), CDesktopUpgradePropertyBag::Read(), read_property_names(), Record_IntegerDataGet(), Record_IntegerDataPut(), record_invoke(), Record_StringDataGet(), Record_StringDataPut(), reg_enum_key(), reg_enum_values(), reg_get_stringvalue(), request_get_property(), request_send(), security_get_sd(), Session_DoAction(), Session_EvaluateCondition(), Session_FeatureCurrentState(), Session_FeatureRequestStateGet(), Session_FeatureRequestStatePut(), session_invoke(), Session_Message(), Session_ModeGet(), Session_ModePut(), Session_PropertyGet(), Session_PropertyPut(), Session_SetInstallLevel(), SHPropertyBag_OnIniFile(), SHPropertyBag_OnMemory(), SHPropertyBag_OnRegKey(), StringList_Item(), summaryinfo_invoke(), SummaryInfo_PropertyGet(), SummaryInfo_PropertyPut(), test_attr_collection_disp(), test_ChangeType_keep_dst(), test_child_col_disp(), test_ClearCustData(), test_codec(), test_com_event_data_(), test_comparemode(), test_container_properties(), test_createProcessingInstruction(), test_CreateTypeLib(), test_CUIAutomation_cache_request_iface(), test_CUIAutomation_condition_ifaces(), test_default_clientside_providers(), test_devenum(), test_directshow_filter(), test_dispatch(), test_DispCallFunc(), test_DispGetParam(), test_dmo(), test_domdoc(), test_domnode(), test_dsound(), test_Element_Find(), test_Element_GetPropertyValue(), test_EmptyChangeTypeEx(), test_ErrorChangeTypeEx(), test_events(), test_Exists(), test_FileCollection(), test_FolderCollection(), test_func(), test_get_dataType(), test_get_ownerDocument(), test_get_xml(), test_getAttribute(), test_GetNames(), test_GetProp(), test_global_id(), test_hash_value(), test_IDispatchChangeTypeEx(), test_IDispatchCopy(), test_IEnumVARIANT(), test_InitVariantFromFileTime(), test_Installer_RegistryValue(), test_interfaces(), test_IUIAutomationEventHandler(), test_IUnknownChangeTypeEx(), test_IUnknownCopy(), test_IWinHttpRequest(), test_IWinHttpRequest_Invoke(), test_Keys(), test_legacy_filter(), test_length(), test_load(), test_locator(), test_marshal_VARIANT(), test_midiout(), test_namespace(), test_NullByRef(), test_NullChangeTypeEx(), test_OleLoadPicturePath(), test_propertybag_write(), test_PropVariantToVariant(), test_registry(), test_Remove(), test_safearray(), test_SafeArrayChangeTypeEx(), test_schema_refs(), test_script_run(), test_ShellExecute(), test_ShellWindows(), test_StaticWidget(), test_StdRegProv(), test_stylesheets(), test_SummaryInfo(), test_SystemSecurity(), test_type_info(), test_TypeInfo(), test_typelibmarshal(), test_uia_element_arr_(), test_uia_prov_from_acc_properties(), test_UiaGetRuntimeId(), test_UiaGetUpdatedCache(), test_VarCat(), test_VariantCopyInd(), test_VariantInit(), test_VariantToPropVariant(), test_VarRound(), test_VarSub(), test_VarUI1FromDisp(), test_vfw(), test_wavein(), test_waveout(), test_Win32_Baseboard(), test_Win32_Bios(), test_Win32_ComputerSystem(), test_Win32_OperatingSystem(), test_Win32_Process(), test_Win32_Processor(), test_Win32_QuickFixEngineering(), test_Win32_Service(), test_Win32_SystemEnclosure(), test_Win32_VideoController(), test_XDR_datatypes(), test_XDR_schemas(), test_XMLHTTP(), test_xmlTypes(), test_XPath(), TLB_AllocAndInitVarDesc(), TLB_copy_all_custdata(), TLB_CopyElemDesc(), TLB_set_custdata(), uia_com_focus_win_event_callback(), uia_com_focus_win_event_handler(), uia_com_focus_win_event_msaa_handler(), uia_condition_clone(), uia_element_get_CurrentBoundingRectangle(), uia_element_get_CurrentControlType(), uia_element_get_CurrentName(), uia_element_GetCachedPropertyValueEx(), uia_element_GetCurrentPropertyValueEx(), uia_nested_node_provider_create_node_from_prov(), uia_nested_node_provider_get_focus(), uia_nested_node_provider_get_prop_val(), uia_nested_node_provider_navigate(), uia_node_get_prop_val(), uia_provider_create_node_from_prov(), uia_provider_get_elem_prop_val(), uia_provider_get_focus(), uia_provider_get_prop_val(), uia_provider_navigate(), uia_raise_serverside_event(), uia_serverside_event_adviser_advise(), validate_regex_document(), VarAbs(), VarAdd(), VarAnd(), VarCat(), VarCmp(), VarDiv(), VarFix(), variant_from_dt(), VARIANT_FromDisp(), VarIdiv(), VarImp(), VarInt(), VarMod(), VarMul(), VarNeg(), VarNot(), VarOr(), VarPow(), VarRound(), VarSub(), VarXor(), View_Execute(), view_invoke(), View_Modify(), WindowFromAccessibleObject(), winhttp_request_Invoke(), winhttp_request_put_Option(), WshShell3_Popup(), WshShell3_RegRead(), WshShell3_RegWrite(), WshShell3_Run(), xmlelem_getAttribute(), and xmlnodelist_invoke().

◆ VariantTimeToDosDateTime()

INT WINAPI VariantTimeToDosDateTime ( double  dateIn,
USHORT pwDosDate,
USHORT pwDosTime 
)

Definition at line 1229 of file variant.c.

1230{
1231 UDATE ud;
1232
1233 TRACE("(%g,%p,%p)\n", dateIn, pwDosDate, pwDosTime);
1234
1235 if (FAILED(VarUdateFromDate(dateIn, 0, &ud)))
1236 return FALSE;
1237
1238 if (ud.st.wYear < 1980 || ud.st.wYear > 2099)
1239 return FALSE;
1240
1241 *pwDosDate = DOS_DATE(ud.st.wDay, ud.st.wMonth, ud.st.wYear);
1242 *pwDosTime = DOS_TIME(ud.st.wHour, ud.st.wMinute, ud.st.wSecond);
1243
1244 TRACE("Returning 0x%x(%d/%d/%d), 0x%x(%d:%d:%d)\n",
1245 *pwDosDate, DOS_YEAR(*pwDosDate), DOS_MONTH(*pwDosDate), DOS_DAY(*pwDosDate),
1246 *pwDosTime, DOS_HOUR(*pwDosTime), DOS_MINUTE(*pwDosTime), DOS_SECOND(*pwDosTime));
1247 return TRUE;
1248}
#define TRUE
Definition: types.h:120
HRESULT WINAPI VarUdateFromDate(DATE dateIn, ULONG dwFlags, UDATE *lpUdate)
Definition: variant.c:1404
#define DOS_DATE(d, m, y)
Definition: variant.c:1081
#define DOS_TIME(h, m, s)
Definition: variant.c:1082

Referenced by test_dt2dos().

◆ VariantTimeToSystemTime()

INT WINAPI VariantTimeToSystemTime ( double  dateIn,
LPSYSTEMTIME  lpSt 
)

Definition at line 1294 of file variant.c.

1295{
1296 UDATE ud;
1297
1298 TRACE("(%g,%p)\n", dateIn, lpSt);
1299
1300 if (FAILED(VarUdateFromDate(dateIn, 0, &ud)))
1301 return FALSE;
1302
1303 *lpSt = ud.st;
1304 return TRUE;
1305}

Referenced by summaryinfo_invoke(), test_dt2st(), to_system_time(), and VarBstrFromDate().

◆ VarIdiv()

HRESULT WINAPI VarIdiv ( LPVARIANT  left,
LPVARIANT  right,
LPVARIANT  result 
)

Definition at line 5248 of file variant.c.

5249{
5250 HRESULT hres = S_OK;
5251 VARTYPE resvt = VT_EMPTY;
5252 VARTYPE leftvt,rightvt;
5253 VARTYPE rightExtraFlags,leftExtraFlags,ExtraFlags;
5254 VARIANT lv,rv;
5255 VARIANT tempLeft, tempRight;
5256
5258
5259 VariantInit(&lv);
5260 VariantInit(&rv);
5261 VariantInit(&tempLeft);
5262 VariantInit(&tempRight);
5263
5264 leftvt = V_VT(left)&VT_TYPEMASK;
5265 rightvt = V_VT(right)&VT_TYPEMASK;
5266 leftExtraFlags = V_VT(left)&(~VT_TYPEMASK);
5267 rightExtraFlags = V_VT(right)&(~VT_TYPEMASK);
5268
5269 if (leftExtraFlags != rightExtraFlags)
5270 {
5272 goto end;
5273 }
5274 ExtraFlags = leftExtraFlags;
5275
5276 /* Native VarIdiv always returns an error when using extra
5277 * flags or if the variant combination is I8 and INT.
5278 */
5279 if ((leftvt == VT_I8 && rightvt == VT_INT) ||
5280 (leftvt == VT_INT && rightvt == VT_I8) ||
5281 (rightvt == VT_EMPTY && leftvt != VT_NULL) ||
5282 ExtraFlags != 0)
5283 {
5285 goto end;
5286 }
5287
5288 /* Determine variant type */
5289 else if (leftvt == VT_NULL || rightvt == VT_NULL)
5290 {
5291 V_VT(result) = VT_NULL;
5292 hres = S_OK;
5293 goto end;
5294 }
5295 else if (leftvt == VT_I8 || rightvt == VT_I8)
5296 resvt = VT_I8;
5297 else if (leftvt == VT_I4 || rightvt == VT_I4 ||
5298 leftvt == VT_INT || rightvt == VT_INT ||
5299 leftvt == VT_UINT || rightvt == VT_UINT ||
5300 leftvt == VT_UI8 || rightvt == VT_UI8 ||
5301 leftvt == VT_UI4 || rightvt == VT_UI4 ||
5302 leftvt == VT_UI2 || rightvt == VT_UI2 ||
5303 leftvt == VT_I1 || rightvt == VT_I1 ||
5304 leftvt == VT_BSTR || rightvt == VT_BSTR ||
5305 leftvt == VT_DATE || rightvt == VT_DATE ||
5306 leftvt == VT_CY || rightvt == VT_CY ||
5307 leftvt == VT_DECIMAL || rightvt == VT_DECIMAL ||
5308 leftvt == VT_R8 || rightvt == VT_R8 ||
5309 leftvt == VT_R4 || rightvt == VT_R4)
5310 resvt = VT_I4;
5311 else if (leftvt == VT_I2 || rightvt == VT_I2 ||
5312 leftvt == VT_BOOL || rightvt == VT_BOOL ||
5313 leftvt == VT_EMPTY)
5314 resvt = VT_I2;
5315 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
5316 resvt = VT_UI1;
5317 else
5318 {
5320 goto end;
5321 }
5322
5323 /* coerce to the result type */
5324 hres = VariantChangeType(&lv, left, 0, resvt);
5325 if (hres != S_OK) goto end;
5326 hres = VariantChangeType(&rv, right, 0, resvt);
5327 if (hres != S_OK) goto end;
5328
5329 /* do the math */
5330 V_VT(result) = resvt;
5331 switch (resvt)
5332 {
5333 case VT_UI1:
5334 if (V_UI1(&rv) == 0)
5335 {
5337 V_VT(result) = VT_EMPTY;
5338 }
5339 else
5340 V_UI1(result) = V_UI1(&lv) / V_UI1(&rv);
5341 break;
5342 case VT_I2:
5343 if (V_I2(&rv) == 0)
5344 {
5346 V_VT(result) = VT_EMPTY;
5347 }
5348 else
5349 V_I2(result) = V_I2(&lv) / V_I2(&rv);
5350 break;
5351 case VT_I4:
5352 if (V_I4(&rv) == 0)
5353 {
5355 V_VT(result) = VT_EMPTY;
5356 }
5357 else
5358 V_I4(result) = V_I4(&lv) / V_I4(&rv);
5359 break;
5360 case VT_I8:
5361 if (V_I8(&rv) == 0)
5362 {
5364 V_VT(result) = VT_EMPTY;
5365 }
5366 else
5367 V_I8(result) = V_I8(&lv) / V_I8(&rv);
5368 break;
5369 default:
5370 FIXME("Couldn't integer divide variant types %d,%d\n",
5371 leftvt,rightvt);
5372 }
5373
5374end:
5375 VariantClear(&lv);
5376 VariantClear(&rv);
5377 VariantClear(&tempLeft);
5378 VariantClear(&tempRight);
5379
5380 return hres;
5381}

Referenced by interp_idiv(), and test_VarIdiv().

◆ VarImp()

HRESULT WINAPI VarImp ( LPVARIANT  left,
LPVARIANT  right,
LPVARIANT  result 
)

Definition at line 5753 of file variant.c.

5754{
5755 HRESULT hres = S_OK;
5756 VARTYPE resvt = VT_EMPTY;
5757 VARTYPE leftvt,rightvt;
5758 VARTYPE rightExtraFlags,leftExtraFlags,ExtraFlags;
5759 VARIANT lv,rv;
5760 double d;
5761 VARIANT tempLeft, tempRight;
5762
5763 VariantInit(&lv);
5764 VariantInit(&rv);
5765 VariantInit(&tempLeft);
5766 VariantInit(&tempRight);
5767
5769
5770 /* Handle VT_DISPATCH by storing and taking address of returned value */
5771 if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
5772 {
5773 hres = VARIANT_FetchDispatchValue(left, &tempLeft);
5774 if (FAILED(hres)) goto VarImp_Exit;
5775 left = &tempLeft;
5776 }
5777 if ((V_VT(right) & VT_TYPEMASK) == VT_DISPATCH)
5778 {
5779 hres = VARIANT_FetchDispatchValue(right, &tempRight);
5780 if (FAILED(hres)) goto VarImp_Exit;
5781 right = &tempRight;
5782 }
5783
5784 leftvt = V_VT(left)&VT_TYPEMASK;
5785 rightvt = V_VT(right)&VT_TYPEMASK;
5786 leftExtraFlags = V_VT(left)&(~VT_TYPEMASK);
5787 rightExtraFlags = V_VT(right)&(~VT_TYPEMASK);
5788
5789 if (leftExtraFlags != rightExtraFlags)
5790 {
5792 goto VarImp_Exit;
5793 }
5794 ExtraFlags = leftExtraFlags;
5795
5796 /* Native VarImp always returns an error when using extra
5797 * flags or if the variants are I8 and INT.
5798 */
5799 if ((leftvt == VT_I8 && rightvt == VT_INT) ||
5800 ExtraFlags != 0)
5801 {
5803 goto VarImp_Exit;
5804 }
5805
5806 /* Determine result type */
5807 else if ((leftvt == VT_NULL && rightvt == VT_NULL) ||
5808 (leftvt == VT_NULL && rightvt == VT_EMPTY))
5809 {
5810 V_VT(result) = VT_NULL;
5811 hres = S_OK;
5812 goto VarImp_Exit;
5813 }
5814 else if (leftvt == VT_I8 || rightvt == VT_I8)
5815 resvt = VT_I8;
5816 else if (leftvt == VT_I4 || rightvt == VT_I4 ||
5817 leftvt == VT_INT || rightvt == VT_INT ||
5818 leftvt == VT_UINT || rightvt == VT_UINT ||
5819 leftvt == VT_UI4 || rightvt == VT_UI4 ||
5820 leftvt == VT_UI8 || rightvt == VT_UI8 ||
5821 leftvt == VT_UI2 || rightvt == VT_UI2 ||
5822 leftvt == VT_DECIMAL || rightvt == VT_DECIMAL ||
5823 leftvt == VT_DATE || rightvt == VT_DATE ||
5824 leftvt == VT_CY || rightvt == VT_CY ||
5825 leftvt == VT_R8 || rightvt == VT_R8 ||
5826 leftvt == VT_R4 || rightvt == VT_R4 ||
5827 leftvt == VT_I1 || rightvt == VT_I1)
5828 resvt = VT_I4;
5829 else if ((leftvt == VT_UI1 && rightvt == VT_UI1) ||
5830 (leftvt == VT_UI1 && rightvt == VT_NULL) ||
5831 (leftvt == VT_NULL && rightvt == VT_UI1))
5832 resvt = VT_UI1;
5833 else if (leftvt == VT_EMPTY || rightvt == VT_EMPTY ||
5834 leftvt == VT_I2 || rightvt == VT_I2 ||
5835 leftvt == VT_UI1 || rightvt == VT_UI1)
5836 resvt = VT_I2;
5837 else if (leftvt == VT_BOOL || rightvt == VT_BOOL ||
5838 leftvt == VT_BSTR || rightvt == VT_BSTR)
5839 resvt = VT_BOOL;
5840
5841 /* VT_NULL requires special handling for when the opposite
5842 * variant is equal to something other than -1.
5843 * (NULL Imp 0 = NULL, NULL Imp n = n)
5844 */
5845 if (leftvt == VT_NULL)
5846 {
5848 switch(rightvt)
5849 {
5850 case VT_I1: if (!V_I1(right)) resvt = VT_NULL; break;
5851 case VT_UI1: if (!V_UI1(right)) resvt = VT_NULL; break;
5852 case VT_I2: if (!V_I2(right)) resvt = VT_NULL; break;
5853 case VT_UI2: if (!V_UI2(right)) resvt = VT_NULL; break;
5854 case VT_I4: if (!V_I4(right)) resvt = VT_NULL; break;
5855 case VT_UI4: if (!V_UI4(right)) resvt = VT_NULL; break;
5856 case VT_I8: if (!V_I8(right)) resvt = VT_NULL; break;
5857 case VT_UI8: if (!V_UI8(right)) resvt = VT_NULL; break;
5858 case VT_INT: if (!V_INT(right)) resvt = VT_NULL; break;
5859 case VT_UINT: if (!V_UINT(right)) resvt = VT_NULL; break;
5860 case VT_BOOL: if (!V_BOOL(right)) resvt = VT_NULL; break;
5861 case VT_R4: if (!V_R4(right)) resvt = VT_NULL; break;
5862 case VT_R8: if (!V_R8(right)) resvt = VT_NULL; break;
5863 case VT_DATE: if (!V_DATE(right)) resvt = VT_NULL; break;
5864 case VT_CY: if (!V_CY(right).int64) resvt = VT_NULL; break;
5865 case VT_DECIMAL:
5866 if (!(V_DECIMAL(right).Hi32 || V_DECIMAL(right).Lo64))
5867 resvt = VT_NULL;
5868 break;
5869 case VT_BSTR:
5871 if (FAILED(hres)) goto VarImp_Exit;
5872 else if (!b)
5873 V_VT(result) = VT_NULL;
5874 else
5875 {
5876 V_VT(result) = VT_BOOL;
5877 V_BOOL(result) = b;
5878 }
5879 goto VarImp_Exit;
5880 }
5881 if (resvt == VT_NULL)
5882 {
5883 V_VT(result) = resvt;
5884 goto VarImp_Exit;
5885 }
5886 else
5887 {
5889 goto VarImp_Exit;
5890 }
5891 }
5892
5893 /* Special handling is required when NULL is the right variant.
5894 * (-1 Imp NULL = NULL, n Imp NULL = n Imp 0)
5895 */
5896 else if (rightvt == VT_NULL)
5897 {
5899 switch(leftvt)
5900 {
5901 case VT_I1: if (V_I1(left) == -1) resvt = VT_NULL; break;
5902 case VT_UI1: if (V_UI1(left) == 0xff) resvt = VT_NULL; break;
5903 case VT_I2: if (V_I2(left) == -1) resvt = VT_NULL; break;
5904 case VT_UI2: if (V_UI2(left) == 0xffff) resvt = VT_NULL; break;
5905 case VT_INT: if (V_INT(left) == -1) resvt = VT_NULL; break;
5906 case VT_UINT: if (V_UINT(left) == ~0u) resvt = VT_NULL; break;
5907 case VT_I4: if (V_I4(left) == -1) resvt = VT_NULL; break;
5908 case VT_UI4: if (V_UI4(left) == ~0u) resvt = VT_NULL; break;
5909 case VT_I8: if (V_I8(left) == -1) resvt = VT_NULL; break;
5910 case VT_UI8: if (V_UI8(left) == ~(ULONGLONG)0) resvt = VT_NULL; break;
5911 case VT_BOOL: if (V_BOOL(left) == VARIANT_TRUE) resvt = VT_NULL; break;
5912 case VT_R4: if (V_R4(left) == -1.0) resvt = VT_NULL; break;
5913 case VT_R8: if (V_R8(left) == -1.0) resvt = VT_NULL; break;
5914 case VT_CY: if (V_CY(left).int64 == -1) resvt = VT_NULL; break;
5915 case VT_DECIMAL:
5916 if (V_DECIMAL(left).Hi32 == 0xffffffff)
5917 resvt = VT_NULL;
5918 break;
5919 case VT_BSTR:
5921 if (FAILED(hres)) goto VarImp_Exit;
5922 else if (b == VARIANT_TRUE)
5923 resvt = VT_NULL;
5924 }
5925 if (resvt == VT_NULL)
5926 {
5927 V_VT(result) = resvt;
5928 goto VarImp_Exit;
5929 }
5930 }
5931
5932 hres = VariantCopy(&lv, left);
5933 if (FAILED(hres)) goto VarImp_Exit;
5934
5935 if (rightvt == VT_NULL)
5936 {
5937 memset( &rv, 0, sizeof(rv) );
5938 V_VT(&rv) = resvt;
5939 }
5940 else
5941 {
5942 hres = VariantCopy(&rv, right);
5943 if (FAILED(hres)) goto VarImp_Exit;
5944 }
5945
5946 if (V_VT(&lv) == VT_BSTR &&
5949 if (SUCCEEDED(hres) && V_VT(&lv) != resvt)
5950 hres = VariantChangeType(&lv,&lv,0,resvt);
5951 if (FAILED(hres)) goto VarImp_Exit;
5952
5953 if (V_VT(&rv) == VT_BSTR &&
5956 if (SUCCEEDED(hres) && V_VT(&rv) != resvt)
5957 hres = VariantChangeType(&rv, &rv, 0, resvt);
5958 if (FAILED(hres)) goto VarImp_Exit;
5959
5960 /* do the math */
5961 V_VT(result) = resvt;
5962 switch (resvt)
5963 {
5964 case VT_I8:
5965 V_I8(result) = (~V_I8(&lv)) | V_I8(&rv);
5966 break;
5967 case VT_I4:
5968 V_I4(result) = (~V_I4(&lv)) | V_I4(&rv);
5969 break;
5970 case VT_I2:
5971 V_I2(result) = (~V_I2(&lv)) | V_I2(&rv);
5972 break;
5973 case VT_UI1:
5974 V_UI1(result) = (~V_UI1(&lv)) | V_UI1(&rv);
5975 break;
5976 case VT_BOOL:
5977 V_BOOL(result) = (~V_BOOL(&lv)) | V_BOOL(&rv);
5978 break;
5979 default:
5980 FIXME("Couldn't perform bitwise implication on variant types %d,%d\n",
5981 leftvt,rightvt);
5982 }
5983
5984VarImp_Exit:
5985
5986 VariantClear(&lv);
5987 VariantClear(&rv);
5988 VariantClear(&tempLeft);
5989 VariantClear(&tempRight);
5990
5991 return hres;
5992}
long long int64
Definition: platform.h:13
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by interp_imp(), and test_VarImp().

◆ VarInt()

HRESULT WINAPI VarInt ( LPVARIANT  pVarIn,
LPVARIANT  pVarOut 
)

Definition at line 4539 of file variant.c.

4540{
4541 HRESULT hRet = S_OK;
4542 VARIANT temp;
4543
4544 VariantInit(&temp);
4545
4546 TRACE("(%s,%p)\n", debugstr_variant(pVarIn), pVarOut);
4547
4548 /* Handle VT_DISPATCH by storing and taking address of returned value */
4549 if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
4550 {
4551 hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
4552 if (FAILED(hRet)) goto VarInt_Exit;
4553 pVarIn = &temp;
4554 }
4555 V_VT(pVarOut) = V_VT(pVarIn);
4556
4557 switch (V_VT(pVarIn))
4558 {
4559 case VT_R4:
4560 V_R4(pVarOut) = (float)floor(V_R4(pVarIn));
4561 break;
4562 case VT_BSTR:
4563 V_VT(pVarOut) = VT_R8;
4564 hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(pVarOut));
4565 pVarIn = pVarOut;
4566 /* Fall through */
4567 case VT_DATE:
4568 case VT_R8:
4569 V_R8(pVarOut) = floor(V_R8(pVarIn));
4570 break;
4571 case VT_CY:
4572 hRet = VarCyInt(V_CY(pVarIn), &V_CY(pVarOut));
4573 break;
4574 case VT_DECIMAL:
4575 hRet = VarDecInt(&V_DECIMAL(pVarIn), &V_DECIMAL(pVarOut));
4576 break;
4577 default:
4578 hRet = VarFix(pVarIn, pVarOut);
4579 }
4580VarInt_Exit:
4582
4583 return hRet;
4584}
HRESULT WINAPI VarCyInt(CY cyIn, CY *pCyOut)
Definition: vartype.c:3920
HRESULT WINAPI VarDecInt(const DECIMAL *pDecIn, DECIMAL *pDecOut)
Definition: vartype.c:5787
HRESULT WINAPI VarFix(LPVARIANT pVarIn, LPVARIANT pVarOut)
Definition: variant.c:4433

Referenced by Global_Int(), and test_VarInt().

◆ VarMod()

HRESULT WINAPI VarMod ( LPVARIANT  left,
LPVARIANT  right,
LPVARIANT  result 
)

Definition at line 5402 of file variant.c.

5403{
5404 HRESULT rc = E_FAIL;
5405 int resT = 0;
5406 VARIANT lv,rv;
5407 VARIANT tempLeft, tempRight;
5408
5409 VariantInit(&tempLeft);
5410 VariantInit(&tempRight);
5411 VariantInit(&lv);
5412 VariantInit(&rv);
5413 V_VT(result) = VT_EMPTY;
5414
5416
5417 /* Handle VT_DISPATCH by storing and taking address of returned value */
5418 if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
5419 {
5420 rc = VARIANT_FetchDispatchValue(left, &tempLeft);
5421 if (FAILED(rc)) goto end;
5422 left = &tempLeft;
5423 }
5424 if ((V_VT(right) & VT_TYPEMASK) == VT_DISPATCH)
5425 {
5426 rc = VARIANT_FetchDispatchValue(right, &tempRight);
5427 if (FAILED(rc)) goto end;
5428 right = &tempRight;
5429 }
5430
5431 /* check for invalid inputs */
5432 switch (V_VT(left) & VT_TYPEMASK) {
5433 case VT_BOOL :
5434 case VT_I1 :
5435 case VT_I2 :
5436 case VT_I4 :
5437 case VT_I8 :
5438 case VT_INT :
5439 case VT_UI1 :
5440 case VT_UI2 :
5441 case VT_UI4 :
5442 case VT_UI8 :
5443 case VT_UINT :
5444 case VT_R4 :
5445 case VT_R8 :
5446 case VT_CY :
5447 case VT_EMPTY:
5448 case VT_DATE :
5449 case VT_BSTR :
5450 case VT_DECIMAL:
5451 break;
5452 case VT_VARIANT:
5453 case VT_UNKNOWN:
5454 V_VT(result) = VT_EMPTY;
5456 goto end;
5457 case VT_ERROR:
5459 goto end;
5460 case VT_RECORD:
5461 V_VT(result) = VT_EMPTY;
5463 goto end;
5464 case VT_NULL:
5465 break;
5466 default:
5467 V_VT(result) = VT_EMPTY;
5468 rc = DISP_E_BADVARTYPE;
5469 goto end;
5470 }
5471
5472
5473 switch (V_VT(right) & VT_TYPEMASK) {
5474 case VT_BOOL :
5475 case VT_I1 :
5476 case VT_I2 :
5477 case VT_I4 :
5478 case VT_I8 :
5479 if((V_VT(left) == VT_INT) && (V_VT(right) == VT_I8))
5480 {
5481 V_VT(result) = VT_EMPTY;
5483 goto end;
5484 }
5485 case VT_INT :
5486 if((V_VT(right) == VT_INT) && (V_VT(left) == VT_I8))
5487 {
5488 V_VT(result) = VT_EMPTY;
5490 goto end;
5491 }
5492 case VT_UI1 :
5493 case VT_UI2 :
5494 case VT_UI4 :
5495 case VT_UI8 :
5496 case VT_UINT :
5497 case VT_R4 :
5498 case VT_R8 :
5499 case VT_CY :
5500 if(V_VT(left) == VT_EMPTY)
5501 {
5502 V_VT(result) = VT_I4;
5503 V_I4(result) = 0;
5504 rc = S_OK;
5505 goto end;
5506 }
5507 case VT_EMPTY:
5508 case VT_DATE :
5509 case VT_DECIMAL:
5510 if(V_VT(left) == VT_ERROR)
5511 {
5512 V_VT(result) = VT_EMPTY;
5514 goto end;
5515 }
5516 case VT_BSTR:
5517 if(V_VT(left) == VT_NULL)
5518 {
5519 V_VT(result) = VT_NULL;
5520 rc = S_OK;
5521 goto end;
5522 }
5523 break;
5524
5525 case VT_VOID:
5526 V_VT(result) = VT_EMPTY;
5527 rc = DISP_E_BADVARTYPE;
5528 goto end;
5529 case VT_NULL:
5530 if(V_VT(left) == VT_VOID)
5531 {
5532 V_VT(result) = VT_EMPTY;
5533 rc = DISP_E_BADVARTYPE;
5534 } else
5535 {
5536 V_VT(result) = VT_NULL;
5537 rc = S_OK;
5538 }
5539 goto end;
5540 case VT_VARIANT:
5541 case VT_UNKNOWN:
5542 V_VT(result) = VT_EMPTY;
5544 goto end;
5545 case VT_ERROR:
5547 goto end;
5548 case VT_RECORD:
5549 if((V_VT(left) == 15) || ((V_VT(left) >= 24) && (V_VT(left) <= 35)))
5550 {
5551 V_VT(result) = VT_EMPTY;
5552 rc = DISP_E_BADVARTYPE;
5553 } else
5554 {
5555 V_VT(result) = VT_EMPTY;
5557 }
5558 goto end;
5559 default:
5560 V_VT(result) = VT_EMPTY;
5561 rc = DISP_E_BADVARTYPE;
5562 goto end;
5563 }
5564
5565 /* determine the result type */
5566 if((V_VT(left) == VT_I8) || (V_VT(right) == VT_I8)) resT = VT_I8;
5567 else if((V_VT(left) == VT_UI1) && (V_VT(right) == VT_BOOL)) resT = VT_I2;
5568 else if((V_VT(left) == VT_UI1) && (V_VT(right) == VT_UI1)) resT = VT_UI1;
5569 else if((V_VT(left) == VT_UI1) && (V_VT(right) == VT_I2)) resT = VT_I2;
5570 else if((V_VT(left) == VT_I2) && (V_VT(right) == VT_BOOL)) resT = VT_I2;
5571 else if((V_VT(left) == VT_I2) && (V_VT(right) == VT_UI1)) resT = VT_I2;
5572 else if((V_VT(left) == VT_I2) && (V_VT(right) == VT_I2)) resT = VT_I2;
5573 else if((V_VT(left) == VT_BOOL) && (V_VT(right) == VT_BOOL)) resT = VT_I2;
5574 else if((V_VT(left) == VT_BOOL) && (V_VT(right) == VT_UI1)) resT = VT_I2;
5575 else if((V_VT(left) == VT_BOOL) && (V_VT(right) == VT_I2)) resT = VT_I2;
5576 else resT = VT_I4; /* most outputs are I4 */
5577
5578 /* convert to I8 for the modulo */
5579 rc = VariantChangeType(&lv, left, 0, VT_I8);
5580 if(FAILED(rc))
5581 {
5582 FIXME("Could not convert left type %d to %d? rc == %#lx.\n", V_VT(left), VT_I8, rc);
5583 goto end;
5584 }
5585
5586 rc = VariantChangeType(&rv, right, 0, VT_I8);
5587 if(FAILED(rc))
5588 {
5589 FIXME("Could not convert right type %d to %d? rc == %#lx.\n", V_VT(right), VT_I8, rc);
5590 goto end;
5591 }
5592
5593 /* if right is zero set VT_EMPTY and return divide by zero */
5594 if(V_I8(&rv) == 0)
5595 {
5596 V_VT(result) = VT_EMPTY;
5597 rc = DISP_E_DIVBYZERO;
5598 goto end;
5599 }
5600
5601 /* perform the modulo operation */
5602 V_VT(result) = VT_I8;
5603 V_I8(result) = V_I8(&lv) % V_I8(&rv);
5604
5605 TRACE("V_I8(left) == %s, V_I8(right) == %s, V_I8(result) == %s\n",
5608
5609 /* convert left and right to the destination type */
5610 rc = VariantChangeType(result, result, 0, resT);
5611 if(FAILED(rc))
5612 {
5613 FIXME("Could not convert 0x%x to %d?\n", V_VT(result), resT);
5614 /* fall to end of function */
5615 }
5616
5617end:
5618 VariantClear(&lv);
5619 VariantClear(&rv);
5620 VariantClear(&tempLeft);
5621 VariantClear(&tempRight);
5622 return rc;
5623}
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49

Referenced by interp_mod(), and test_VarMod().

◆ VarMul()

HRESULT WINAPI VarMul ( LPVARIANT  left,
LPVARIANT  right,
LPVARIANT  result 
)

Definition at line 3407 of file variant.c.

3408{
3409 HRESULT hres;
3410 VARTYPE lvt, rvt, resvt, tvt;
3411 VARIANT lv, rv, tv;
3412 VARIANT tempLeft, tempRight;
3413 double r8res;
3414
3415 /* Variant priority for coercion. Sorted from lowest to highest.
3416 VT_ERROR shows an invalid input variant type. */
3417 enum coerceprio { vt_UI1 = 0, vt_I2, vt_I4, vt_I8, vt_CY, vt_R4, vt_R8,
3418 vt_DECIMAL, vt_NULL, vt_ERROR };
3419 /* Mapping from priority to variant type. Keep in sync with coerceprio! */
3420 static const VARTYPE prio2vt[] = { VT_UI1, VT_I2, VT_I4, VT_I8, VT_CY, VT_R4, VT_R8,
3422
3423 /* Mapping for coercion from input variant to priority of result variant. */
3424 static const VARTYPE coerce[] = {
3425 /* VT_EMPTY, VT_NULL, VT_I2, VT_I4, VT_R4 */
3426 vt_UI1, vt_NULL, vt_I2, vt_I4, vt_R4,
3427 /* VT_R8, VT_CY, VT_DATE, VT_BSTR, VT_DISPATCH */
3428 vt_R8, vt_CY, vt_R8, vt_R8, vt_ERROR,
3429 /* VT_ERROR, VT_BOOL, VT_VARIANT, VT_UNKNOWN, VT_DECIMAL */
3430 vt_ERROR, vt_I2, vt_ERROR, vt_ERROR, vt_DECIMAL,
3431 /* 15, VT_I1, VT_UI1, VT_UI2, VT_UI4 VT_I8 */
3432 vt_ERROR, vt_ERROR, vt_UI1, vt_ERROR, vt_ERROR, vt_I8
3433 };
3434
3436
3437 VariantInit(&lv);
3438 VariantInit(&rv);
3439 VariantInit(&tv);
3440 VariantInit(&tempLeft);
3441 VariantInit(&tempRight);
3442
3443 /* Handle VT_DISPATCH by storing and taking address of returned value */
3444 if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
3445 {
3446 hres = VARIANT_FetchDispatchValue(left, &tempLeft);
3447 if (FAILED(hres)) goto end;
3448 left = &tempLeft;
3449 }
3450 if ((V_VT(right) & VT_TYPEMASK) == VT_DISPATCH)
3451 {
3452 hres = VARIANT_FetchDispatchValue(right, &tempRight);
3453 if (FAILED(hres)) goto end;
3454 right = &tempRight;
3455 }
3456
3457 lvt = V_VT(left)&VT_TYPEMASK;
3458 rvt = V_VT(right)&VT_TYPEMASK;
3459
3460 /* If we have any flag set (VT_ARRAY, VT_VECTOR, etc.) bail out.
3461 Same for any input variant type > VT_I8 */
3462 if (V_VT(left) & ~VT_TYPEMASK || V_VT(right) & ~VT_TYPEMASK ||
3463 lvt > VT_I8 || rvt > VT_I8) {
3465 goto end;
3466 }
3467
3468 /* Determine the variant type to coerce to. */
3469 if (coerce[lvt] > coerce[rvt]) {
3470 resvt = prio2vt[coerce[lvt]];
3471 tvt = prio2vt[coerce[rvt]];
3472 } else {
3473 resvt = prio2vt[coerce[rvt]];
3474 tvt = prio2vt[coerce[lvt]];
3475 }
3476
3477 /* Special cases where the result variant type is defined by both
3478 input variants and not only that with the highest priority */
3479 if (resvt == VT_R4 && (tvt == VT_CY || tvt == VT_I8 || tvt == VT_I4))
3480 resvt = VT_R8;
3481 if (lvt == VT_EMPTY && rvt == VT_EMPTY)
3482 resvt = VT_I2;
3483
3484 /* For overflow detection use the biggest compatible type for the
3485 multiplication */
3486 switch (resvt) {
3487 case VT_ERROR:
3489 goto end;
3490 case VT_NULL:
3491 hres = S_OK;
3492 V_VT(result) = VT_NULL;
3493 goto end;
3494 case VT_UI1:
3495 case VT_I2:
3496 case VT_I4:
3497 case VT_I8:
3498 tvt = VT_I8;
3499 break;
3500 case VT_R4:
3501 tvt = VT_R8;
3502 break;
3503 default:
3504 tvt = resvt;
3505 }
3506
3507 /* Now coerce the variants */
3508 hres = VariantChangeType(&lv, left, 0, tvt);
3509 if (FAILED(hres))
3510 goto end;
3511 hres = VariantChangeType(&rv, right, 0, tvt);
3512 if (FAILED(hres))
3513 goto end;
3514
3515 /* Do the math */
3516 hres = S_OK;
3517 V_VT(&tv) = tvt;
3518 V_VT(result) = resvt;
3519 switch (tvt) {
3520 case VT_DECIMAL:
3521 hres = VarDecMul(&V_DECIMAL(&lv), &V_DECIMAL(&rv),
3522 &V_DECIMAL(result));
3523 goto end;
3524 case VT_CY:
3525 hres = VarCyMul(V_CY(&lv), V_CY(&rv), &V_CY(result));
3526 goto end;
3527 case VT_I8:
3528 /* Overflow detection */
3529 r8res = (double)V_I8(&lv) * (double)V_I8(&rv);
3530 if (r8res > (double)I8_MAX || r8res < (double)I8_MIN) {
3531 V_VT(result) = VT_R8;
3532 V_R8(result) = r8res;
3533 goto end;
3534 } else
3535 V_I8(&tv) = V_I8(&lv) * V_I8(&rv);
3536 break;
3537 case VT_R8:
3538 /* FIXME: overflow detection */
3539 V_R8(&tv) = V_R8(&lv) * V_R8(&rv);
3540 break;
3541 default:
3542 ERR("We shouldn't get here! tvt = %d!\n", tvt);
3543 break;
3544 }
3545 if (resvt != tvt) {
3546 while ((hres = VariantChangeType(result, &tv, 0, resvt)) != S_OK) {
3547 /* Overflow! Change to the vartype with the next higher priority.
3548 With one exception: I4 ==> R8 even if it would fit in I8 */
3549 if (resvt == VT_I4)
3550 resvt = VT_R8;
3551 else
3552 resvt = prio2vt[coerce[resvt] + 1];
3553 }
3554 } else
3555 hres = VariantCopy(result, &tv);
3556
3557end:
3558 if (hres != S_OK) {
3559 V_VT(result) = VT_EMPTY;
3560 V_I4(result) = 0; /* No V_EMPTY */
3561 }
3562 VariantClear(&lv);
3563 VariantClear(&rv);
3564 VariantClear(&tv);
3565 VariantClear(&tempLeft);
3566 VariantClear(&tempRight);
3567 TRACE("returning %#lx, %s\n", hres, debugstr_variant(result));
3568 return hres;
3569}
HRESULT WINAPI VarCyMul(CY cyLeft, CY cyRight, CY *pCyOut)
Definition: vartype.c:3802
HRESULT WINAPI VarDecMul(const DECIMAL *pDecLeft, const DECIMAL *pDecRight, DECIMAL *pDecOut)
Definition: vartype.c:5647

Referenced by interp_mul(), and test_VarMul().

◆ VarNeg()

HRESULT WINAPI VarNeg ( LPVARIANT  pVarIn,
LPVARIANT  pVarOut 
)

Definition at line 4846 of file variant.c.

4847{
4848 HRESULT hRet = S_OK;
4849 VARIANT temp;
4850
4851 VariantInit(&temp);
4852
4853 TRACE("(%s,%p)\n", debugstr_variant(pVarIn), pVarOut);
4854
4855 /* Handle VT_DISPATCH by storing and taking address of returned value */
4856 if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
4857 {
4858 hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
4859 if (FAILED(hRet)) goto VarNeg_Exit;
4860 pVarIn = &temp;
4861 }
4862 V_VT(pVarOut) = V_VT(pVarIn);
4863
4864 switch (V_VT(pVarIn))
4865 {
4866 case VT_UI1:
4867 V_VT(pVarOut) = VT_I2;
4868 V_I2(pVarOut) = -V_UI1(pVarIn);
4869 break;
4870 case VT_BOOL:
4871 V_VT(pVarOut) = VT_I2;
4872 /* Fall through */
4873 case VT_I2:
4874 if (V_I2(pVarIn) == I2_MIN)
4875 {
4876 V_VT(pVarOut) = VT_I4;
4877 V_I4(pVarOut) = -(int)V_I2(pVarIn);
4878 }
4879 else
4880 V_I2(pVarOut) = -V_I2(pVarIn);
4881 break;
4882 case VT_I4:
4883 if (V_I4(pVarIn) == I4_MIN)
4884 {
4885 V_VT(pVarOut) = VT_R8;
4886 V_R8(pVarOut) = -(double)V_I4(pVarIn);
4887 }
4888 else
4889 V_I4(pVarOut) = -V_I4(pVarIn);
4890 break;
4891 case VT_I8:
4892 if (V_I8(pVarIn) == I8_MIN)
4893 {
4894 V_VT(pVarOut) = VT_R8;
4895 hRet = VarR8FromI8(V_I8(pVarIn), &V_R8(pVarOut));
4896 V_R8(pVarOut) *= -1.0;
4897 }
4898 else
4899 V_I8(pVarOut) = -V_I8(pVarIn);
4900 break;
4901 case VT_R4:
4902 V_R4(pVarOut) = -V_R4(pVarIn);
4903 break;
4904 case VT_DATE:
4905 case VT_R8:
4906 V_R8(pVarOut) = -V_R8(pVarIn);
4907 break;
4908 case VT_CY:
4909 hRet = VarCyNeg(V_CY(pVarIn), &V_CY(pVarOut));
4910 break;
4911 case VT_DECIMAL:
4912 hRet = VarDecNeg(&V_DECIMAL(pVarIn), &V_DECIMAL(pVarOut));
4913 break;
4914 case VT_BSTR:
4915 V_VT(pVarOut) = VT_R8;
4916 hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(pVarOut));
4917 V_R8(pVarOut) = -V_R8(pVarOut);
4918 break;
4919 case VT_EMPTY:
4920 V_VT(pVarOut) = VT_I2;
4921 V_I2(pVarOut) = 0;
4922 break;
4923 case VT_NULL:
4924 /* No-Op */
4925 break;
4926 default:
4927 if (V_TYPE(pVarIn) == VT_CLSID || /* VT_CLSID is a special case */
4929 hRet = DISP_E_BADVARTYPE;
4930 else
4931 hRet = DISP_E_TYPEMISMATCH;
4932 }
4933VarNeg_Exit:
4934 if (FAILED(hRet))
4935 V_VT(pVarOut) = VT_EMPTY;
4937
4938 return hRet;
4939}
HRESULT WINAPI VarDecNeg(const DECIMAL *pDecIn, DECIMAL *pDecOut)
Definition: vartype.c:5819
HRESULT WINAPI VarCyNeg(CY cyIn, CY *pCyOut)
Definition: vartype.c:3945
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31

Referenced by interp_neg(), and test_VarNeg().

◆ VarNot()

HRESULT WINAPI VarNot ( LPVARIANT  pVarIn,
LPVARIANT  pVarOut 
)

Definition at line 4974 of file variant.c.

4975{
4976 VARIANT varIn;
4977 HRESULT hRet = S_OK;
4978 VARIANT temp;
4979
4980 VariantInit(&temp);
4981
4982 TRACE("(%s,%p)\n", debugstr_variant(pVarIn), pVarOut);
4983
4984 /* Handle VT_DISPATCH by storing and taking address of returned value */
4985 if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
4986 {
4987 hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
4988 if (FAILED(hRet)) goto VarNot_Exit;
4989 pVarIn = &temp;
4990 }
4991
4992 if (V_VT(pVarIn) == VT_BSTR)
4993 {
4994 V_VT(&varIn) = VT_R8;
4995 hRet = VarR8FromStr( V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn) );
4996 if (FAILED(hRet))
4997 {
4998 V_VT(&varIn) = VT_BOOL;
4999 hRet = VarBoolFromStr( V_BSTR(pVarIn), LOCALE_USER_DEFAULT, VAR_LOCALBOOL, &V_BOOL(&varIn) );
5000 }
5001 if (FAILED(hRet)) goto VarNot_Exit;
5002 pVarIn = &varIn;
5003 }
5004
5005 V_VT(pVarOut) = V_VT(pVarIn);
5006
5007 switch (V_VT(pVarIn))
5008 {
5009 case VT_I1:
5010 V_I4(pVarOut) = ~V_I1(pVarIn);
5011 V_VT(pVarOut) = VT_I4;
5012 break;
5013 case VT_UI1: V_UI1(pVarOut) = ~V_UI1(pVarIn); break;
5014 case VT_BOOL:
5015 case VT_I2: V_I2(pVarOut) = ~V_I2(pVarIn); break;
5016 case VT_UI2:
5017 V_I4(pVarOut) = ~V_UI2(pVarIn);
5018 V_VT(pVarOut) = VT_I4;
5019 break;
5020 case VT_DECIMAL:
5021 hRet = VarI4FromDec(&V_DECIMAL(pVarIn), &V_I4(&varIn));
5022 if (FAILED(hRet))
5023 break;
5024 pVarIn = &varIn;
5025 /* Fall through ... */
5026 case VT_INT:
5027 V_VT(pVarOut) = VT_I4;
5028 /* Fall through ... */
5029 case VT_I4: V_I4(pVarOut) = ~V_I4(pVarIn); break;
5030 case VT_UINT:
5031 case VT_UI4:
5032 V_I4(pVarOut) = ~V_UI4(pVarIn);
5033 V_VT(pVarOut) = VT_I4;
5034 break;
5035 case VT_I8: V_I8(pVarOut) = ~V_I8(pVarIn); break;
5036 case VT_UI8:
5037 V_I4(pVarOut) = ~V_UI8(pVarIn);
5038 V_VT(pVarOut) = VT_I4;
5039 break;
5040 case VT_R4:
5041 hRet = VarI4FromR4(V_R4(pVarIn), &V_I4(pVarOut));
5042 V_I4(pVarOut) = ~V_I4(pVarOut);
5043 V_VT(pVarOut) = VT_I4;
5044 break;
5045 case VT_DATE:
5046 case VT_R8:
5047 hRet = VarI4FromR8(V_R8(pVarIn), &V_I4(pVarOut));
5048 V_I4(pVarOut) = ~V_I4(pVarOut);
5049 V_VT(pVarOut) = VT_I4;
5050 break;
5051 case VT_CY:
5052 hRet = VarI4FromCy(V_CY(pVarIn), &V_I4(pVarOut));
5053 V_I4(pVarOut) = ~V_I4(pVarOut);
5054 V_VT(pVarOut) = VT_I4;
5055 break;
5056 case VT_EMPTY:
5057 V_I2(pVarOut) = ~0;
5058 V_VT(pVarOut) = VT_I2;
5059 break;
5060 case VT_NULL:
5061 /* No-Op */
5062 break;
5063 default:
5064 if (V_TYPE(pVarIn) == VT_CLSID || /* VT_CLSID is a special case */
5066 hRet = DISP_E_BADVARTYPE;
5067 else
5068 hRet = DISP_E_TYPEMISMATCH;
5069 }
5070VarNot_Exit:
5071 if (FAILED(hRet))
5072 V_VT(pVarOut) = VT_EMPTY;
5074
5075 return hRet;
5076}

Referenced by interp_not(), and test_VarNot().

◆ VarNumFromParseNum()

HRESULT WINAPI VarNumFromParseNum ( NUMPARSE pNumprs,
BYTE rgbDig,
ULONG  dwVtBits,
VARIANT pVarDst 
)

Definition at line 2060 of file variant.c.

2062{
2063 /* Scale factors and limits for double arithmetic */
2064 static const double dblMultipliers[11] = {
2065 1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0,
2066 1000000.0, 10000000.0, 100000000.0, 1000000000.0, 10000000000.0
2067 };
2068 static const double dblMinimums[11] = {
2069 R8_MIN, R8_MIN*10.0, R8_MIN*100.0, R8_MIN*1000.0, R8_MIN*10000.0,
2070 R8_MIN*100000.0, R8_MIN*1000000.0, R8_MIN*10000000.0,
2071 R8_MIN*100000000.0, R8_MIN*1000000000.0, R8_MIN*10000000000.0
2072 };
2073 static const double dblMaximums[11] = {
2074 R8_MAX, R8_MAX/10.0, R8_MAX/100.0, R8_MAX/1000.0, R8_MAX/10000.0,
2075 R8_MAX/100000.0, R8_MAX/1000000.0, R8_MAX/10000000.0,
2076 R8_MAX/100000000.0, R8_MAX/1000000000.0, R8_MAX/10000000000.0
2077 };
2078
2079 int wholeNumberDigits, fractionalDigits, divisor10 = 0, multiplier10 = 0;
2080
2081 TRACE("%p, %p, %lx, %p.\n", pNumprs, rgbDig, dwVtBits, pVarDst);
2082
2083 if (pNumprs->nBaseShift)
2084 {
2085 /* nBaseShift indicates a hex or octal number */
2086 ULONG64 ul64 = 0;
2087 LONG64 l64;
2088 int i;
2089
2090 /* Convert the hex or octal number string into a UI64 */
2091 for (i = 0; i < pNumprs->cDig; i++)
2092 {
2093 if (ul64 > ((UI8_MAX>>pNumprs->nBaseShift) - rgbDig[i]))
2094 {
2095 TRACE("Overflow multiplying digits\n");
2096 return DISP_E_OVERFLOW;
2097 }
2098 ul64 = (ul64<<pNumprs->nBaseShift) + rgbDig[i];
2099 }
2100
2101 /* also make a negative representation */
2102 l64=-ul64;
2103
2104 /* Try signed and unsigned types in size order */
2105 if (dwVtBits & VTBIT_I1 && FITS_AS_I1(ul64))
2106 {
2107 V_VT(pVarDst) = VT_I1;
2108 V_I1(pVarDst) = ul64;
2109 return S_OK;
2110 }
2111 else if (dwVtBits & VTBIT_UI1 && FITS_AS_I1(ul64))
2112 {
2113 V_VT(pVarDst) = VT_UI1;
2114 V_UI1(pVarDst) = ul64;
2115 return S_OK;
2116 }
2117 else if (dwVtBits & VTBIT_I2 && FITS_AS_I2(ul64))
2118 {
2119 V_VT(pVarDst) = VT_I2;
2120 V_I2(pVarDst) = ul64;
2121 return S_OK;
2122 }
2123 else if (dwVtBits & VTBIT_UI2 && FITS_AS_I2(ul64))
2124 {
2125 V_VT(pVarDst) = VT_UI2;
2126 V_UI2(pVarDst) = ul64;
2127 return S_OK;
2128 }
2129 else if (dwVtBits & VTBIT_I4 && FITS_AS_I4(ul64))
2130 {
2131 V_VT(pVarDst) = VT_I4;
2132 V_I4(pVarDst) = ul64;
2133 return S_OK;
2134 }
2135 else if (dwVtBits & VTBIT_UI4 && FITS_AS_I4(ul64))
2136 {
2137 V_VT(pVarDst) = VT_UI4;
2138 V_UI4(pVarDst) = ul64;
2139 return S_OK;
2140 }
2141 else if (dwVtBits & VTBIT_I8 && ((ul64 <= I8_MAX)||(l64>=I8_MIN)))
2142 {
2143 V_VT(pVarDst) = VT_I8;
2144 V_I8(pVarDst) = ul64;
2145 return S_OK;
2146 }
2147 else if (dwVtBits & VTBIT_UI8)
2148 {
2149 V_VT(pVarDst) = VT_UI8;
2150 V_UI8(pVarDst) = ul64;
2151 return S_OK;
2152 }
2153 else if ((dwVtBits & VTBIT_DECIMAL) == VTBIT_DECIMAL)
2154 {
2155 V_VT(pVarDst) = VT_DECIMAL;
2156 V_DECIMAL(pVarDst).sign = DECIMAL_POS;
2157 V_DECIMAL(pVarDst).scale = 0;
2158 V_DECIMAL(pVarDst).Hi32 = 0;
2159 V_DECIMAL(pVarDst).Lo64 = ul64;
2160 return S_OK;
2161 }
2162 else if (dwVtBits & VTBIT_R4 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN)))
2163 {
2164 V_VT(pVarDst) = VT_R4;
2165 if (ul64 <= I4_MAX)
2166 V_R4(pVarDst) = ul64;
2167 else
2168 V_R4(pVarDst) = l64;
2169 return S_OK;
2170 }
2171 else if (dwVtBits & VTBIT_R8 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN)))
2172 {
2173 V_VT(pVarDst) = VT_R8;
2174 if (ul64 <= I4_MAX)
2175 V_R8(pVarDst) = ul64;
2176 else
2177 V_R8(pVarDst) = l64;
2178 return S_OK;
2179 }
2180
2181 TRACE("Overflow: possible return types: %#lx, value: %s\n", dwVtBits, wine_dbgstr_longlong(ul64));
2182 return DISP_E_OVERFLOW;
2183 }
2184
2185 /* Count the number of relevant fractional and whole digits stored,
2186 * And compute the divisor/multiplier to scale the number by.
2187 */
2188 if (pNumprs->nPwr10 < 0)
2189 {
2190 if (-pNumprs->nPwr10 >= pNumprs->cDig)
2191 {
2192 /* A real number < +/- 1.0 e.g. 0.1024 or 0.01024 */
2193 wholeNumberDigits = 0;
2194 fractionalDigits = pNumprs->cDig;
2195 divisor10 = -pNumprs->nPwr10;
2196 }
2197 else
2198 {
2199 /* An exactly represented real number e.g. 1.024 */
2200 wholeNumberDigits = pNumprs->cDig + pNumprs->nPwr10;
2201 fractionalDigits = pNumprs->cDig - wholeNumberDigits;
2202 divisor10 = pNumprs->cDig - wholeNumberDigits;
2203 }
2204 }
2205 else if (pNumprs->nPwr10 == 0)
2206 {
2207 /* An exactly represented whole number e.g. 1024 */
2208 wholeNumberDigits = pNumprs->cDig;
2209 fractionalDigits = 0;
2210 }
2211 else /* pNumprs->nPwr10 > 0 */
2212 {
2213 /* A whole number followed by nPwr10 0's e.g. 102400 */
2214 wholeNumberDigits = pNumprs->cDig;
2215 fractionalDigits = 0;
2216 multiplier10 = pNumprs->nPwr10;
2217 }
2218
2219 TRACE("cDig %d; nPwr10 %d, whole %d, frac %d mult %d; div %d\n",
2220 pNumprs->cDig, pNumprs->nPwr10, wholeNumberDigits, fractionalDigits,
2221 multiplier10, divisor10);
2222
2223 if (dwVtBits & (INTEGER_VTBITS|VTBIT_DECIMAL) &&
2224 (!fractionalDigits || !(dwVtBits & (REAL_VTBITS|VTBIT_DECIMAL))))
2225 {
2226 /* We have one or more integer output choices, and either:
2227 * 1) An integer input value, or
2228 * 2) A real number input value but no floating output choices.
2229 * Alternately, we have a DECIMAL output available and an integer input.
2230 *
2231 * So, place the integer value into pVarDst, using the smallest type
2232 * possible and preferring signed over unsigned types.
2233 */
2234 BOOL bOverflow = FALSE, bNegative;
2235 ULONG64 ul64 = 0;
2236 int i;
2237
2238 /* Convert the integer part of the number into a UI8 */
2239 for (i = 0; i < wholeNumberDigits; i++)
2240 {
2241 if (ul64 > UI8_MAX / 10 || (ul64 == UI8_MAX / 10 && rgbDig[i] > UI8_MAX % 10))
2242 {
2243 TRACE("Overflow multiplying digits\n");
2244 bOverflow = TRUE;
2245 break;
2246 }
2247 ul64 = ul64 * 10 + rgbDig[i];
2248 }
2249
2250 /* Account for the scale of the number */
2251 if (!bOverflow && multiplier10)
2252 {
2253 for (i = 0; i < multiplier10; i++)
2254 {
2255 if (ul64 > (UI8_MAX / 10))
2256 {
2257 TRACE("Overflow scaling number\n");
2258 bOverflow = TRUE;
2259 break;
2260 }
2261 ul64 = ul64 * 10;
2262 }
2263 }
2264
2265 /* If we have any fractional digits, round the value.
2266 * Note we don't have to do this if divisor10 is < 1,
2267 * because this means the fractional part must be < 0.5
2268 */
2269 if (!bOverflow && fractionalDigits && divisor10 > 0)
2270 {
2271 const BYTE* fracDig = rgbDig + wholeNumberDigits;
2272 BOOL bAdjust = FALSE;
2273
2274 TRACE("first decimal value is %d\n", *fracDig);
2275
2276 if (*fracDig > 5)
2277 bAdjust = TRUE; /* > 0.5 */
2278 else if (*fracDig == 5)
2279 {
2280 for (i = 1; i < fractionalDigits; i++)
2281 {
2282 if (fracDig[i])
2283 {
2284 bAdjust = TRUE; /* > 0.5 */
2285 break;
2286 }
2287 }
2288 /* If exactly 0.5, round only odd values */
2289 if (i == fractionalDigits && (ul64 & 1))
2290 bAdjust = TRUE;
2291 }
2292
2293 if (bAdjust)
2294 {
2295 if (ul64 == UI8_MAX)
2296 {
2297 TRACE("Overflow after rounding\n");
2298 bOverflow = TRUE;
2299 }
2300 ul64++;
2301 }
2302 }
2303
2304 /* Zero is not a negative number */
2305 bNegative = pNumprs->dwOutFlags & NUMPRS_NEG && ul64;
2306
2307 TRACE("Integer value is 0x%s, bNeg %d\n", wine_dbgstr_longlong(ul64), bNegative);
2308
2309 /* For negative integers, try the signed types in size order */
2310 if (!bOverflow && bNegative)
2311 {
2312 if (dwVtBits & (VTBIT_I1|VTBIT_I2|VTBIT_I4|VTBIT_I8))
2313 {
2314 if (dwVtBits & VTBIT_I1 && ul64 <= -I1_MIN)
2315 {
2316 V_VT(pVarDst) = VT_I1;
2317 V_I1(pVarDst) = -ul64;
2318 return S_OK;
2319 }
2320 else if (dwVtBits & VTBIT_I2 && ul64 <= -I2_MIN)
2321 {
2322 V_VT(pVarDst) = VT_I2;
2323 V_I2(pVarDst) = -ul64;
2324 return S_OK;
2325 }
2326 else if (dwVtBits & VTBIT_I4 && ul64 <= -((LONGLONG)I4_MIN))
2327 {
2328 V_VT(pVarDst) = VT_I4;
2329 V_I4(pVarDst) = -ul64;
2330 return S_OK;
2331 }
2332 else if (dwVtBits & VTBIT_I8 && ul64 <= (ULONGLONG)I8_MAX + 1)
2333 {
2334 V_VT(pVarDst) = VT_I8;
2335 V_I8(pVarDst) = -ul64;
2336 return S_OK;
2337 }
2338 else if ((dwVtBits & (REAL_VTBITS|VTBIT_DECIMAL)) == VTBIT_DECIMAL)
2339 {
2340 /* Decimal is only output choice left - fast path */
2341 V_VT(pVarDst) = VT_DECIMAL;
2342 V_DECIMAL(pVarDst).sign = DECIMAL_NEG;
2343 V_DECIMAL(pVarDst).scale = 0;
2344 V_DECIMAL(pVarDst).Hi32 = 0;
2345 V_DECIMAL(pVarDst).Lo64 = -ul64;
2346 return S_OK;
2347 }
2348 }
2349 }
2350 else if (!bOverflow)
2351 {
2352 /* For positive integers, try signed then unsigned types in size order */
2353 if (dwVtBits & VTBIT_I1 && ul64 <= I1_MAX)
2354 {
2355 V_VT(pVarDst) = VT_I1;
2356 V_I1(pVarDst) = ul64;
2357 return S_OK;
2358 }
2359 else if (dwVtBits & VTBIT_UI1 && ul64 <= UI1_MAX)
2360 {
2361 V_VT(pVarDst) = VT_UI1;
2362 V_UI1(pVarDst) = ul64;
2363 return S_OK;
2364 }
2365 else if (dwVtBits & VTBIT_I2 && ul64 <= I2_MAX)
2366 {
2367 V_VT(pVarDst) = VT_I2;
2368 V_I2(pVarDst) = ul64;
2369 return S_OK;
2370 }
2371 else if (dwVtBits & VTBIT_UI2 && ul64 <= UI2_MAX)
2372 {
2373 V_VT(pVarDst) = VT_UI2;
2374 V_UI2(pVarDst) = ul64;
2375 return S_OK;
2376 }
2377 else if (dwVtBits & VTBIT_I4 && ul64 <= I4_MAX)
2378 {
2379 V_VT(pVarDst) = VT_I4;
2380 V_I4(pVarDst) = ul64;
2381 return S_OK;
2382 }
2383 else if (dwVtBits & VTBIT_UI4 && ul64 <= UI4_MAX)
2384 {
2385 V_VT(pVarDst) = VT_UI4;
2386 V_UI4(pVarDst) = ul64;
2387 return S_OK;
2388 }
2389 else if (dwVtBits & VTBIT_I8 && ul64 <= I8_MAX)
2390 {
2391 V_VT(pVarDst) = VT_I8;
2392 V_I8(pVarDst) = ul64;
2393 return S_OK;
2394 }
2395 else if (dwVtBits & VTBIT_UI8)
2396 {
2397 V_VT(pVarDst) = VT_UI8;
2398 V_UI8(pVarDst) = ul64;
2399 return S_OK;
2400 }
2401 else if ((dwVtBits & (REAL_VTBITS|VTBIT_DECIMAL)) == VTBIT_DECIMAL)
2402 {
2403 /* Decimal is only output choice left - fast path */
2404 V_VT(pVarDst) = VT_DECIMAL;
2405 V_DECIMAL(pVarDst).sign = DECIMAL_POS;
2406 V_DECIMAL(pVarDst).scale = 0;
2407 V_DECIMAL(pVarDst).Hi32 = 0;
2408 V_DECIMAL(pVarDst).Lo64 = ul64;
2409 return S_OK;
2410 }
2411 }
2412 }
2413
2414 if (dwVtBits & REAL_VTBITS)
2415 {
2416 /* Try to put the number into a float or real */
2417 BOOL bOverflow = FALSE, bNegative = pNumprs->dwOutFlags & NUMPRS_NEG;
2418 double whole = 0.0;
2419 int i;
2420
2421 /* Convert the number into a double */
2422 for (i = 0; i < pNumprs->cDig; i++)
2423 whole = whole * 10.0 + rgbDig[i];
2424
2425 TRACE("Whole double value is %16.16g\n", whole);
2426
2427 /* Account for the scale */
2428 while (multiplier10 > 10)
2429 {
2430 if (whole > dblMaximums[10])
2431 {
2432 dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY);
2433 bOverflow = TRUE;
2434 break;
2435 }
2436 whole = whole * dblMultipliers[10];
2437 multiplier10 -= 10;
2438 }
2439 if (multiplier10 && !bOverflow)
2440 {
2441 if (whole > dblMaximums[multiplier10])
2442 {
2443 dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY);
2444 bOverflow = TRUE;
2445 }
2446 else
2447 whole = whole * dblMultipliers[multiplier10];
2448 }
2449
2450 if (!bOverflow)
2451 TRACE("Scaled double value is %16.16g\n", whole);
2452
2453 while (divisor10 > 10 && !bOverflow)
2454 {
2455 if (whole < dblMinimums[10] && whole != 0)
2456 {
2457 whole = 0; /* ignore underflow */
2458 divisor10 = 0;
2459 break;
2460 }
2461 whole = whole / dblMultipliers[10];
2462 divisor10 -= 10;
2463 }
2464 if (divisor10 && !bOverflow)
2465 {
2466 if (whole < dblMinimums[divisor10] && whole != 0)
2467 {
2468 whole = 0; /* ignore underflow */
2469 divisor10 = 0;
2470 }
2471 else
2472 whole = whole / dblMultipliers[divisor10];
2473 }
2474 if (!bOverflow)
2475 TRACE("Final double value is %16.16g\n", whole);
2476
2477 if (dwVtBits & VTBIT_R4 &&
2478 ((whole <= R4_MAX && whole >= R4_MIN) || whole == 0.0))
2479 {
2480 TRACE("Set R4 to final value\n");
2481 V_VT(pVarDst) = VT_R4; /* Fits into a float */
2482 V_R4(pVarDst) = pNumprs->dwOutFlags & NUMPRS_NEG ? -whole : whole;
2483 return S_OK;
2484 }
2485
2486 if (dwVtBits & VTBIT_R8)
2487 {
2488 TRACE("Set R8 to final value\n");
2489 V_VT(pVarDst) = VT_R8; /* Fits into a double */
2490 V_R8(pVarDst) = pNumprs->dwOutFlags & NUMPRS_NEG ? -whole : whole;
2491 return S_OK;
2492 }
2493
2494 if (dwVtBits & VTBIT_CY)
2495 {
2496 if (SUCCEEDED(VarCyFromR8(bNegative ? -whole : whole, &V_CY(pVarDst))))
2497 {
2498 V_VT(pVarDst) = VT_CY; /* Fits into a currency */
2499 TRACE("Set CY to final value\n");
2500 return S_OK;
2501 }
2502 TRACE("Value Overflows CY\n");
2503 }
2504 }
2505
2506 if (dwVtBits & VTBIT_DECIMAL)
2507 {
2508 int i;
2509 ULONG carry;
2510 ULONG64 tmp;
2511 DECIMAL* pDec = &V_DECIMAL(pVarDst);
2512
2513 DECIMAL_SETZERO(*pDec);
2514 pDec->Lo32 = 0;
2515
2516 if (pNumprs->dwOutFlags & NUMPRS_NEG)
2517 pDec->sign = DECIMAL_NEG;
2518 else
2519 pDec->sign = DECIMAL_POS;
2520
2521 /* Factor the significant digits */
2522 for (i = 0; i < pNumprs->cDig; i++)
2523 {
2524 tmp = (ULONG64)pDec->Lo32 * 10 + rgbDig[i];
2525 carry = (ULONG)(tmp >> 32);
2526 pDec->Lo32 = (ULONG)tmp;
2527 tmp = (ULONG64)pDec->Mid32 * 10 + carry;
2528 carry = (ULONG)(tmp >> 32);
2529 pDec->Mid32 = (ULONG)tmp;
2530 tmp = (ULONG64)pDec->Hi32 * 10 + carry;
2531 pDec->Hi32 = (ULONG)tmp;
2532
2533 if (tmp >> 32)
2534 {
2535VarNumFromParseNum_DecOverflow:
2536 TRACE("Overflow\n");
2537 pDec->Lo32 = pDec->Mid32 = pDec->Hi32 = UI4_MAX;
2538 return DISP_E_OVERFLOW;
2539 }
2540 }
2541
2542 /* Account for the scale of the number */
2543 while (multiplier10 > 0)
2544 {
2545 tmp = (ULONG64)pDec->Lo32 * 10;
2546 carry = (ULONG)(tmp >> 32);
2547 pDec->Lo32 = (ULONG)tmp;
2548 tmp = (ULONG64)pDec->Mid32 * 10 + carry;
2549 carry = (ULONG)(tmp >> 32);
2550 pDec->Mid32 = (ULONG)tmp;
2551 tmp = (ULONG64)pDec->Hi32 * 10 + carry;
2552 pDec->Hi32 = (ULONG)tmp;
2553
2554 if (tmp >> 32)
2555 goto VarNumFromParseNum_DecOverflow;
2556 multiplier10--;
2557 }
2558 pDec->scale = divisor10;
2559
2560 V_VT(pVarDst) = VT_DECIMAL;
2561 return S_OK;
2562 }
2563 return DISP_E_OVERFLOW; /* No more output choices */
2564}
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned __int64 ULONG64
Definition: imports.h:198
#define NUMPRS_NEG
Definition: oleauto.h:749
#define VTBIT_I2
Definition: oleauto.h:754
#define VTBIT_UI1
Definition: oleauto.h:753
#define VTBIT_I8
Definition: oleauto.h:758
#define VTBIT_I4
Definition: oleauto.h:756
INT cDig
Definition: oleauto.h:727
ULONG dwOutFlags
Definition: oleauto.h:729
INT nBaseShift
Definition: oleauto.h:731
INT nPwr10
Definition: oleauto.h:732
ULONG Hi32
Definition: compat.h:2276
BYTE sign
Definition: compat.h:2272
ULONG Lo32
Definition: compat.h:2283
BYTE scale
Definition: compat.h:2271
ULONG Mid32
Definition: compat.h:2284
int64_t LONG64
Definition: typedefs.h:68
#define REAL_VTBITS
Definition: variant.c:2023
#define FITS_AS_I1(x)
Definition: variant.c:2026
#define FITS_AS_I2(x)
Definition: variant.c:2027
#define INTEGER_VTBITS
Definition: variant.c:2021
#define FITS_AS_I4(x)
Definition: variant.c:2028
#define I4_MAX
Definition: variant.h:59
#define I2_MAX
Definition: variant.h:55
#define UI2_MAX
Definition: variant.h:57
#define R4_MIN
Definition: variant.h:70
#define UI8_MAX
Definition: variant.h:65
#define UI4_MAX
Definition: variant.h:61
#define R8_MIN
Definition: variant.h:72
#define I1_MAX
Definition: variant.h:51
#define R8_MAX
Definition: variant.h:71
#define UI1_MAX
Definition: variant.h:53

Referenced by VARIANT_NumberFromBstr().

◆ VarOr()

HRESULT WINAPI VarOr ( LPVARIANT  pVarLeft,
LPVARIANT  pVarRight,
LPVARIANT  pVarOut 
)

Definition at line 4015 of file variant.c.

4016{
4017 VARTYPE vt = VT_I4;
4018 VARIANT varLeft, varRight, varStr;
4019 HRESULT hRet;
4020 VARIANT tempLeft, tempRight;
4021
4022 VariantInit(&tempLeft);
4023 VariantInit(&tempRight);
4024 VariantInit(&varLeft);
4025 VariantInit(&varRight);
4026 VariantInit(&varStr);
4027
4028 TRACE("(%s,%s,%p)\n", debugstr_variant(pVarLeft), debugstr_variant(pVarRight), pVarOut);
4029
4030 /* Handle VT_DISPATCH by storing and taking address of returned value */
4031 if ((V_VT(pVarLeft) & VT_TYPEMASK) == VT_DISPATCH)
4032 {
4033 hRet = VARIANT_FetchDispatchValue(pVarLeft, &tempLeft);
4034 if (FAILED(hRet)) goto VarOr_Exit;
4035 pVarLeft = &tempLeft;
4036 }
4037 if ((V_VT(pVarRight) & VT_TYPEMASK) == VT_DISPATCH)
4038 {
4039 hRet = VARIANT_FetchDispatchValue(pVarRight, &tempRight);
4040 if (FAILED(hRet)) goto VarOr_Exit;
4041 pVarRight = &tempRight;
4042 }
4043
4044 if (V_EXTRA_TYPE(pVarLeft) || V_EXTRA_TYPE(pVarRight) ||
4045 V_VT(pVarLeft) == VT_UNKNOWN || V_VT(pVarRight) == VT_UNKNOWN ||
4046 V_VT(pVarLeft) == VT_DISPATCH || V_VT(pVarRight) == VT_DISPATCH ||
4047 V_VT(pVarLeft) == VT_RECORD || V_VT(pVarRight) == VT_RECORD)
4048 {
4049 hRet = DISP_E_BADVARTYPE;
4050 goto VarOr_Exit;
4051 }
4052
4053 V_VT(&varLeft) = V_VT(&varRight) = V_VT(&varStr) = VT_EMPTY;
4054
4055 if (V_VT(pVarLeft) == VT_NULL || V_VT(pVarRight) == VT_NULL)
4056 {
4057 /* NULL OR Zero is NULL, NULL OR value is value */
4058 if (V_VT(pVarLeft) == VT_NULL)
4059 pVarLeft = pVarRight; /* point to the non-NULL var */
4060
4061 V_VT(pVarOut) = VT_NULL;
4062 V_I4(pVarOut) = 0;
4063
4064 switch (V_VT(pVarLeft))
4065 {
4066 case VT_DATE: case VT_R8:
4067 if (V_R8(pVarLeft))
4068 goto VarOr_AsEmpty;
4069 hRet = S_OK;
4070 goto VarOr_Exit;
4071 case VT_BOOL:
4072 if (V_BOOL(pVarLeft))
4073 *pVarOut = *pVarLeft;
4074 hRet = S_OK;
4075 goto VarOr_Exit;
4076 case VT_I2: case VT_UI2:
4077 if (V_I2(pVarLeft))
4078 goto VarOr_AsEmpty;
4079 hRet = S_OK;
4080 goto VarOr_Exit;
4081 case VT_I1:
4082 if (V_I1(pVarLeft))
4083 goto VarOr_AsEmpty;
4084 hRet = S_OK;
4085 goto VarOr_Exit;
4086 case VT_UI1:
4087 if (V_UI1(pVarLeft))
4088 *pVarOut = *pVarLeft;
4089 hRet = S_OK;
4090 goto VarOr_Exit;
4091 case VT_R4:
4092 if (V_R4(pVarLeft))
4093 goto VarOr_AsEmpty;
4094 hRet = S_OK;
4095 goto VarOr_Exit;
4096 case VT_I4: case VT_UI4: case VT_INT: case VT_UINT:
4097 if (V_I4(pVarLeft))
4098 goto VarOr_AsEmpty;
4099 hRet = S_OK;
4100 goto VarOr_Exit;
4101 case VT_CY:
4102 if (V_CY(pVarLeft).int64)
4103 goto VarOr_AsEmpty;
4104 hRet = S_OK;
4105 goto VarOr_Exit;
4106 case VT_I8: case VT_UI8:
4107 if (V_I8(pVarLeft))
4108 goto VarOr_AsEmpty;
4109 hRet = S_OK;
4110 goto VarOr_Exit;
4111 case VT_DECIMAL:
4112 if (V_DECIMAL(pVarLeft).Hi32 || V_DECIMAL(pVarLeft).Lo64)
4113 goto VarOr_AsEmpty;
4114 hRet = S_OK;
4115 goto VarOr_Exit;
4116 case VT_BSTR:
4117 {
4119
4120 if (!V_BSTR(pVarLeft))
4121 {
4122 hRet = DISP_E_BADVARTYPE;
4123 goto VarOr_Exit;
4124 }
4125
4127 if (SUCCEEDED(hRet) && b)
4128 {
4129 V_VT(pVarOut) = VT_BOOL;
4130 V_BOOL(pVarOut) = b;
4131 }
4132 goto VarOr_Exit;
4133 }
4134 case VT_NULL: case VT_EMPTY:
4135 V_VT(pVarOut) = VT_NULL;
4136 hRet = S_OK;
4137 goto VarOr_Exit;
4138 default:
4139 hRet = DISP_E_BADVARTYPE;
4140 goto VarOr_Exit;
4141 }
4142 }
4143
4144 if (V_VT(pVarLeft) == VT_EMPTY || V_VT(pVarRight) == VT_EMPTY)
4145 {
4146 if (V_VT(pVarLeft) == VT_EMPTY)
4147 pVarLeft = pVarRight; /* point to the non-EMPTY var */
4148
4149VarOr_AsEmpty:
4150 /* Since one argument is empty (0), OR'ing it with the other simply
4151 * gives the others value (as 0|x => x). So just convert the other
4152 * argument to the required result type.
4153 */
4154 switch (V_VT(pVarLeft))
4155 {
4156 case VT_BSTR:
4157 if (!V_BSTR(pVarLeft))
4158 {
4159 hRet = DISP_E_BADVARTYPE;
4160 goto VarOr_Exit;
4161 }
4162
4163 hRet = VariantCopy(&varStr, pVarLeft);
4164 if (FAILED(hRet))
4165 goto VarOr_Exit;
4166 pVarLeft = &varStr;
4167 hRet = VariantChangeType(pVarLeft, pVarLeft, 0, VT_BOOL);
4168 if (FAILED(hRet))
4169 goto VarOr_Exit;
4170 /* Fall Through ... */
4171 case VT_EMPTY: case VT_UI1: case VT_BOOL: case VT_I2:
4172 V_VT(pVarOut) = VT_I2;
4173 break;
4174 case VT_DATE: case VT_CY: case VT_DECIMAL: case VT_R4: case VT_R8:
4175 case VT_I1: case VT_UI2: case VT_I4: case VT_UI4:
4176 case VT_INT: case VT_UINT: case VT_UI8:
4177 V_VT(pVarOut) = VT_I4;
4178 break;
4179 case VT_I8:
4180 V_VT(pVarOut) = VT_I8;
4181 break;
4182 default:
4183 hRet = DISP_E_BADVARTYPE;
4184 goto VarOr_Exit;
4185 }
4186 hRet = VariantCopy(&varLeft, pVarLeft);
4187 if (FAILED(hRet))
4188 goto VarOr_Exit;
4189 pVarLeft = &varLeft;
4190 hRet = VariantChangeType(pVarOut, pVarLeft, 0, V_VT(pVarOut));
4191 goto VarOr_Exit;
4192 }
4193
4194 if (V_VT(pVarLeft) == VT_BOOL && V_VT(pVarRight) == VT_BOOL)
4195 {
4196 V_VT(pVarOut) = VT_BOOL;
4197 V_BOOL(pVarOut) = V_BOOL(pVarLeft) | V_BOOL(pVarRight);
4198 hRet = S_OK;
4199 goto VarOr_Exit;
4200 }
4201
4202 if (V_VT(pVarLeft) == VT_UI1 && V_VT(pVarRight) == VT_UI1)
4203 {
4204 V_VT(pVarOut) = VT_UI1;
4205 V_UI1(pVarOut) = V_UI1(pVarLeft) | V_UI1(pVarRight);
4206 hRet = S_OK;
4207 goto VarOr_Exit;
4208 }
4209
4210 if (V_VT(pVarLeft) == VT_BSTR)
4211 {
4212 hRet = VariantCopy(&varStr, pVarLeft);
4213 if (FAILED(hRet))
4214 goto VarOr_Exit;
4215 pVarLeft = &varStr;
4216 hRet = VariantChangeType(pVarLeft, pVarLeft, 0, VT_BOOL);
4217 if (FAILED(hRet))
4218 goto VarOr_Exit;
4219 }
4220
4221 if (V_VT(pVarLeft) == VT_BOOL &&
4222 (V_VT(pVarRight) == VT_BOOL || V_VT(pVarRight) == VT_BSTR))
4223 {
4224 vt = VT_BOOL;
4225 }
4226 else if ((V_VT(pVarLeft) == VT_BOOL || V_VT(pVarLeft) == VT_UI1 ||
4227 V_VT(pVarLeft) == VT_I2 || V_VT(pVarLeft) == VT_BSTR) &&
4228 (V_VT(pVarRight) == VT_BOOL || V_VT(pVarRight) == VT_UI1 ||
4229 V_VT(pVarRight) == VT_I2 || V_VT(pVarRight) == VT_BSTR))
4230 {
4231 vt = VT_I2;
4232 }
4233 else if (V_VT(pVarLeft) == VT_I8 || V_VT(pVarRight) == VT_I8)
4234 {
4235 if (V_VT(pVarLeft) == VT_INT || V_VT(pVarRight) == VT_INT)
4236 {
4237 hRet = DISP_E_TYPEMISMATCH;
4238 goto VarOr_Exit;
4239 }
4240 vt = VT_I8;
4241 }
4242
4243 hRet = VariantCopy(&varLeft, pVarLeft);
4244 if (FAILED(hRet))
4245 goto VarOr_Exit;
4246
4247 hRet = VariantCopy(&varRight, pVarRight);
4248 if (FAILED(hRet))
4249 goto VarOr_Exit;
4250
4251 if (vt == VT_I4 && V_VT(&varLeft) == VT_UI4)
4252 V_VT(&varLeft) = VT_I4; /* Don't overflow */
4253 else
4254 {
4255 double d;
4256
4257 if (V_VT(&varLeft) == VT_BSTR &&
4259 hRet = VariantChangeType(&varLeft, &varLeft, VARIANT_LOCALBOOL, VT_BOOL);
4260 if (SUCCEEDED(hRet) && V_VT(&varLeft) != vt)
4261 hRet = VariantChangeType(&varLeft, &varLeft, 0, vt);
4262 if (FAILED(hRet))
4263 goto VarOr_Exit;
4264 }
4265
4266 if (vt == VT_I4 && V_VT(&varRight) == VT_UI4)
4267 V_VT(&varRight) = VT_I4; /* Don't overflow */
4268 else
4269 {
4270 double d;
4271
4272 if (V_VT(&varRight) == VT_BSTR &&
4273 FAILED(VarR8FromStr(V_BSTR(&varRight), LOCALE_USER_DEFAULT, 0, &d)))
4274 hRet = VariantChangeType(&varRight, &varRight, VARIANT_LOCALBOOL, VT_BOOL);
4275 if (SUCCEEDED(hRet) && V_VT(&varRight) != vt)
4276 hRet = VariantChangeType(&varRight, &varRight, 0, vt);
4277 if (FAILED(hRet))
4278 goto VarOr_Exit;
4279 }
4280
4281 V_VT(pVarOut) = vt;
4282 if (vt == VT_I8)
4283 {
4284 V_I8(pVarOut) = V_I8(&varLeft) | V_I8(&varRight);
4285 }
4286 else if (vt == VT_I4)
4287 {
4288 V_I4(pVarOut) = V_I4(&varLeft) | V_I4(&varRight);
4289 }
4290 else
4291 {
4292 V_I2(pVarOut) = V_I2(&varLeft) | V_I2(&varRight);
4293 }
4294
4295VarOr_Exit:
4296 VariantClear(&varStr);
4297 VariantClear(&varLeft);
4298 VariantClear(&varRight);
4299 VariantClear(&tempLeft);
4300 VariantClear(&tempRight);
4301 return hRet;
4302}
#define V_EXTRA_TYPE(v)
Definition: variant.h:34

Referenced by interp_or(), and test_VarOr().

◆ VarParseNumFromStr()

HRESULT WINAPI VarParseNumFromStr ( const OLECHAR lpszStr,
LCID  lcid,
ULONG  dwFlags,
NUMPARSE pNumprs,
BYTE rgbDig 
)

Definition at line 1578 of file variant.c.

1580{
1582 BYTE rgbTmp[1024];
1584 int iMaxDigits = ARRAY_SIZE(rgbTmp);
1585 int cchUsed = 0;
1586 OLECHAR cDigitSeparator2;
1587
1588 TRACE("%s, %#lx, %#lx, %p, %p.\n", debugstr_w(lpszStr), lcid, dwFlags, pNumprs, rgbDig);
1589
1590 if (!pNumprs || !rgbDig)
1591 return E_INVALIDARG;
1592
1593 if (pNumprs->cDig < iMaxDigits)
1594 iMaxDigits = pNumprs->cDig;
1595
1596 pNumprs->cDig = 0;
1597 pNumprs->dwOutFlags = 0;
1598 pNumprs->cchUsed = 0;
1599 pNumprs->nBaseShift = 0;
1600 pNumprs->nPwr10 = 0;
1601
1602 if (!lpszStr)
1603 return DISP_E_TYPEMISMATCH;
1604
1606 if (chars.cDigitSeparator == chars.cDecimalPoint)
1607 /* The decimal point completely masks the digit separator */
1608 chars.cDigitSeparator = 0;
1609 /* Setting the thousands separator to a non-breaking space implies regular
1610 * spaces are allowed too. But the converse is not true.
1611 */
1612 cDigitSeparator2 = chars.cDigitSeparator == 0xa0 ? ' ' : 0;
1613
1614 /* First consume all the leading symbols and space from the string */
1615 while (1)
1616 {
1617 if (pNumprs->dwInFlags & NUMPRS_DECIMAL &&
1618 (*lpszStr == chars.cDecimalPoint ||
1619 *lpszStr == chars.cCurrencyDecimalPoint))
1620 {
1621 pNumprs->dwOutFlags |= NUMPRS_DECIMAL;
1622 if (*lpszStr == chars.cCurrencyDecimalPoint &&
1623 chars.cDecimalPoint != chars.cCurrencyDecimalPoint)
1624 pNumprs->dwOutFlags |= NUMPRS_CURRENCY;
1625 cchUsed++;
1626 lpszStr++;
1627
1628 /* If we have no digits so far, skip leading zeros */
1629 if (!pNumprs->cDig)
1630 {
1631 while (*lpszStr == '0')
1632 {
1633 dwState |= B_LEADING_ZERO;
1634 cchUsed++;
1635 lpszStr++;
1636 pNumprs->nPwr10--;
1637 }
1638 }
1639 break;
1640 }
1641 else if (pNumprs->dwInFlags & NUMPRS_LEADING_WHITE && iswspace(*lpszStr))
1642 {
1643 pNumprs->dwOutFlags |= NUMPRS_LEADING_WHITE;
1644 do
1645 {
1646 cchUsed++;
1647 lpszStr++;
1648 } while (iswspace(*lpszStr));
1649 }
1650 else if (pNumprs->dwInFlags & NUMPRS_THOUSANDS &&
1651 ((chars.cDigitSeparator && *lpszStr == chars.cDigitSeparator) ||
1652 (cDigitSeparator2 && *lpszStr == cDigitSeparator2)))
1653 {
1654 return DISP_E_TYPEMISMATCH; /* Not allowed before the first digit */
1655 }
1657 chars.cCurrencyDigitSeparator && *lpszStr == chars.cCurrencyDigitSeparator)
1658 {
1659 return DISP_E_TYPEMISMATCH; /* Not allowed before the first digit */
1660 }
1661 else if (pNumprs->dwInFlags & NUMPRS_LEADING_PLUS &&
1662 *lpszStr == chars.cPositiveSymbol &&
1663 !(pNumprs->dwOutFlags & NUMPRS_LEADING_PLUS))
1664 {
1665 pNumprs->dwOutFlags |= NUMPRS_LEADING_PLUS;
1666 cchUsed++;
1667 lpszStr++;
1668 }
1669 else if (pNumprs->dwInFlags & NUMPRS_LEADING_MINUS &&
1670 *lpszStr == chars.cNegativeSymbol &&
1671 !(pNumprs->dwOutFlags & NUMPRS_LEADING_MINUS))
1672 {
1674 cchUsed++;
1675 lpszStr++;
1676 }
1677 else if (pNumprs->dwInFlags & NUMPRS_CURRENCY &&
1678 !(pNumprs->dwOutFlags & NUMPRS_CURRENCY) &&
1679 wcsncmp(lpszStr, chars.sCurrency, chars.sCurrencyLen) == 0)
1680 {
1681 pNumprs->dwOutFlags |= NUMPRS_CURRENCY;
1682 cchUsed += chars.sCurrencyLen;
1683 lpszStr += chars.sCurrencyLen;
1684 }
1685 else if (pNumprs->dwInFlags & NUMPRS_PARENS && *lpszStr == '(' &&
1686 !(pNumprs->dwOutFlags & NUMPRS_PARENS))
1687 {
1688 pNumprs->dwOutFlags |= NUMPRS_PARENS;
1689 cchUsed++;
1690 lpszStr++;
1691 }
1692 else
1693 break;
1694 }
1695
1696 if (!(pNumprs->dwOutFlags & (NUMPRS_CURRENCY|NUMPRS_DECIMAL)))
1697 {
1698 if ((*lpszStr == '&' && (*(lpszStr+1) == 'H' || *(lpszStr+1) == 'h')) &&
1699 pNumprs->dwInFlags & NUMPRS_HEX_OCT)
1700 {
1701 dwState |= B_PROCESSING_HEX;
1702 pNumprs->dwOutFlags |= NUMPRS_HEX_OCT;
1703 cchUsed=cchUsed+2;
1704 lpszStr=lpszStr+2;
1705 }
1706 else if ((*lpszStr == '&' && (*(lpszStr+1) == 'O' || *(lpszStr+1) == 'o')) &&
1707 pNumprs->dwInFlags & NUMPRS_HEX_OCT)
1708 {
1709 dwState |= B_PROCESSING_OCT;
1710 pNumprs->dwOutFlags |= NUMPRS_HEX_OCT;
1711 cchUsed=cchUsed+2;
1712 lpszStr=lpszStr+2;
1713 }
1714 }
1715
1716 /* Strip Leading zeros */
1717 while (*lpszStr == '0')
1718 {
1719 dwState |= B_LEADING_ZERO;
1720 cchUsed++;
1721 lpszStr++;
1722 }
1723
1724 while (*lpszStr)
1725 {
1726 if (is_digit(*lpszStr))
1727 {
1728 if (dwState & B_PROCESSING_EXPONENT)
1729 {
1730 int exponentSize = 0;
1731 if (dwState & B_EXPONENT_START)
1732 {
1733 if (!is_digit(*lpszStr))
1734 break; /* No exponent digits - invalid */
1735 while (*lpszStr == '0')
1736 {
1737 /* Skip leading zero's in the exponent */
1738 cchUsed++;
1739 lpszStr++;
1740 }
1741 }
1742
1743 while (is_digit(*lpszStr))
1744 {
1745 exponentSize *= 10;
1746 exponentSize += *lpszStr - '0';
1747 cchUsed++;
1748 lpszStr++;
1749 }
1750 if (dwState & B_NEGATIVE_EXPONENT)
1751 exponentSize = -exponentSize;
1752 /* Add the exponent into the powers of 10 */
1753 pNumprs->nPwr10 += exponentSize;
1755 lpszStr--; /* back up to allow processing of next char */
1756 }
1757 else
1758 {
1759 if ((pNumprs->cDig >= iMaxDigits) && !(dwState & B_PROCESSING_HEX)
1760 && !(dwState & B_PROCESSING_OCT))
1761 {
1762 pNumprs->dwOutFlags |= NUMPRS_INEXACT;
1763
1764 if (*lpszStr != '0')
1765 dwState &= ~B_INEXACT_ZEROS; /* Inexact number with non-trailing zeros */
1766
1767 /* This digit can't be represented, but count it in nPwr10 */
1768 if (pNumprs->dwOutFlags & NUMPRS_DECIMAL)
1769 pNumprs->nPwr10--;
1770 else
1771 pNumprs->nPwr10++;
1772 }
1773 else
1774 {
1775 if ((dwState & B_PROCESSING_OCT) && ((*lpszStr == '8') || (*lpszStr == '9')))
1776 break;
1777
1778 if (pNumprs->dwOutFlags & NUMPRS_DECIMAL)
1779 pNumprs->nPwr10--; /* Count decimal points in nPwr10 */
1780
1781 rgbTmp[pNumprs->cDig] = *lpszStr - '0';
1782 }
1783 pNumprs->cDig++;
1784 cchUsed++;
1785 }
1786 }
1787 else if (pNumprs->dwInFlags & NUMPRS_THOUSANDS &&
1788 !(pNumprs->dwOutFlags & NUMPRS_HEX_OCT) &&
1789 ((chars.cDigitSeparator && *lpszStr == chars.cDigitSeparator) ||
1790 (cDigitSeparator2 && *lpszStr == cDigitSeparator2)))
1791 {
1792 pNumprs->dwOutFlags |= NUMPRS_THOUSANDS;
1793 cchUsed++;
1794 }
1796 !(pNumprs->dwOutFlags & NUMPRS_HEX_OCT) &&
1797 chars.cCurrencyDigitSeparator && *lpszStr == chars.cCurrencyDigitSeparator)
1798 {
1800 cchUsed++;
1801 }
1802 else if (pNumprs->dwInFlags & NUMPRS_DECIMAL &&
1803 (*lpszStr == chars.cDecimalPoint ||
1804 *lpszStr == chars.cCurrencyDecimalPoint) &&
1806 {
1807 pNumprs->dwOutFlags |= NUMPRS_DECIMAL;
1808 if (*lpszStr == chars.cCurrencyDecimalPoint &&
1809 chars.cDecimalPoint != chars.cCurrencyDecimalPoint)
1810 pNumprs->dwOutFlags |= NUMPRS_CURRENCY;
1811 cchUsed++;
1812
1813 /* If we have no digits so far, skip leading zeros */
1814 if (!pNumprs->cDig)
1815 {
1816 while (lpszStr[1] == '0')
1817 {
1818 dwState |= B_LEADING_ZERO;
1819 cchUsed++;
1820 lpszStr++;
1821 pNumprs->nPwr10--;
1822 }
1823 }
1824 }
1825 else if (((*lpszStr >= 'a' && *lpszStr <= 'f') ||
1826 (*lpszStr >= 'A' && *lpszStr <= 'F')) &&
1827 dwState & B_PROCESSING_HEX)
1828 {
1829 if (pNumprs->cDig >= iMaxDigits)
1830 {
1831 return DISP_E_OVERFLOW;
1832 }
1833 else
1834 {
1835 if (*lpszStr >= 'a')
1836 rgbTmp[pNumprs->cDig] = *lpszStr - 'a' + 10;
1837 else
1838 rgbTmp[pNumprs->cDig] = *lpszStr - 'A' + 10;
1839 }
1840 pNumprs->cDig++;
1841 cchUsed++;
1842 }
1843 else if ((*lpszStr == 'e' || *lpszStr == 'E') &&
1844 pNumprs->dwInFlags & NUMPRS_EXPONENT &&
1846 {
1847 dwState |= B_PROCESSING_EXPONENT;
1848 pNumprs->dwOutFlags |= NUMPRS_EXPONENT;
1849 cchUsed++;
1850 }
1851 else if (dwState & B_PROCESSING_EXPONENT && *lpszStr == chars.cPositiveSymbol)
1852 {
1853 cchUsed++; /* Ignore positive exponent */
1854 }
1855 else if (dwState & B_PROCESSING_EXPONENT && *lpszStr == chars.cNegativeSymbol)
1856 {
1857 dwState |= B_NEGATIVE_EXPONENT;
1858 cchUsed++;
1859 }
1860 else
1861 break; /* Stop at an unrecognised character */
1862
1863 lpszStr++;
1864 }
1865
1866 if (!pNumprs->cDig && dwState & B_LEADING_ZERO)
1867 {
1868 /* Ensure a 0 on its own gets stored */
1869 pNumprs->cDig = 1;
1870 rgbTmp[0] = 0;
1871 }
1872
1873 if (pNumprs->dwOutFlags & NUMPRS_EXPONENT && dwState & B_PROCESSING_EXPONENT)
1874 {
1875 pNumprs->cchUsed = cchUsed;
1876 WARN("didn't completely parse exponent\n");
1877 return DISP_E_TYPEMISMATCH; /* Failed to completely parse the exponent */
1878 }
1879
1880 if (pNumprs->dwOutFlags & NUMPRS_INEXACT)
1881 {
1882 if (dwState & B_INEXACT_ZEROS)
1883 pNumprs->dwOutFlags &= ~NUMPRS_INEXACT; /* All zeros doesn't set NUMPRS_INEXACT */
1884 } else if(pNumprs->dwInFlags & NUMPRS_HEX_OCT)
1885 {
1886 /* copy all of the digits into the output digit buffer */
1887 /* this is exactly what windows does although it also returns */
1888 /* cDig of X and writes X+Y where Y>=0 number of digits to rgbDig */
1889 memcpy(rgbDig, rgbTmp, pNumprs->cDig * sizeof(BYTE));
1890
1891 if (dwState & B_PROCESSING_HEX) {
1892 /* hex numbers have always the same format */
1893 pNumprs->nPwr10=0;
1894 pNumprs->nBaseShift=4;
1895 } else {
1896 if (dwState & B_PROCESSING_OCT) {
1897 /* oct numbers have always the same format */
1898 pNumprs->nPwr10=0;
1899 pNumprs->nBaseShift=3;
1900 } else {
1901 while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1])
1902 {
1903 pNumprs->nPwr10++;
1904 pNumprs->cDig--;
1905 }
1906 }
1907 }
1908 } else
1909 {
1910 /* Remove trailing zeros from the last (whole number or decimal) part */
1911 while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1])
1912 {
1913 pNumprs->nPwr10++;
1914 pNumprs->cDig--;
1915 }
1916 }
1917
1918 if (pNumprs->cDig <= iMaxDigits)
1919 pNumprs->dwOutFlags &= ~NUMPRS_INEXACT; /* Ignore stripped zeros for NUMPRS_INEXACT */
1920 else
1921 pNumprs->cDig = iMaxDigits; /* Only return iMaxDigits worth of digits */
1922
1923 /* Copy the digits we processed into rgbDig */
1924 memcpy(rgbDig, rgbTmp, pNumprs->cDig * sizeof(BYTE));
1925
1926 /* Consume any trailing symbols and space */
1927 while (1)
1928 {
1929 if ((chars.cDigitSeparator && *lpszStr == chars.cDigitSeparator) ||
1930 (cDigitSeparator2 && *lpszStr == cDigitSeparator2))
1931 {
1932 if (pNumprs->dwInFlags & NUMPRS_THOUSANDS &&
1933 !(pNumprs->dwOutFlags & NUMPRS_HEX_OCT))
1934 {
1935 pNumprs->dwOutFlags |= NUMPRS_THOUSANDS;
1936 cchUsed++;
1937 lpszStr++;
1938 }
1939 else
1940 {
1941 /* Not allowed, even with NUMPRS_TRAILING_WHITE */
1942 break;
1943 }
1944 }
1945 else if (*lpszStr == chars.cCurrencyDigitSeparator)
1946 {
1948 !(pNumprs->dwOutFlags & NUMPRS_HEX_OCT))
1949 {
1951 cchUsed++;
1952 lpszStr++;
1953 }
1954 else
1955 {
1956 /* Not allowed, even with NUMPRS_TRAILING_WHITE */
1957 break;
1958 }
1959 }
1960 else if ((pNumprs->dwInFlags & NUMPRS_TRAILING_WHITE) && iswspace(*lpszStr))
1961 {
1963 do
1964 {
1965 cchUsed++;
1966 lpszStr++;
1967 } while (iswspace(*lpszStr));
1968 }
1969 else if (pNumprs->dwInFlags & NUMPRS_TRAILING_PLUS &&
1970 !(pNumprs->dwOutFlags & NUMPRS_LEADING_PLUS) &&
1971 *lpszStr == chars.cPositiveSymbol)
1972 {
1973 pNumprs->dwOutFlags |= NUMPRS_TRAILING_PLUS;
1974 cchUsed++;
1975 lpszStr++;
1976 }
1977 else if (pNumprs->dwInFlags & NUMPRS_TRAILING_MINUS &&
1978 !(pNumprs->dwOutFlags & NUMPRS_LEADING_MINUS) &&
1979 *lpszStr == chars.cNegativeSymbol)
1980 {
1982 cchUsed++;
1983 lpszStr++;
1984 }
1985 else if (pNumprs->dwInFlags & NUMPRS_PARENS && *lpszStr == ')' &&
1986 pNumprs->dwOutFlags & NUMPRS_PARENS)
1987 {
1988 cchUsed++;
1989 lpszStr++;
1990 pNumprs->dwOutFlags |= NUMPRS_NEG;
1991 }
1992 else if (pNumprs->dwInFlags & NUMPRS_CURRENCY &&
1993 !(pNumprs->dwOutFlags & NUMPRS_HEX_OCT) &&
1994 wcsncmp(lpszStr, chars.sCurrency, chars.sCurrencyLen) == 0)
1995 {
1996 pNumprs->dwOutFlags |= NUMPRS_CURRENCY;
1997 cchUsed += chars.sCurrencyLen;
1998 lpszStr += chars.sCurrencyLen;
1999 }
2000 else
2001 break;
2002 }
2003
2004 if (pNumprs->dwOutFlags & NUMPRS_PARENS && !(pNumprs->dwOutFlags & NUMPRS_NEG))
2005 {
2006 pNumprs->cchUsed = cchUsed;
2007 return DISP_E_TYPEMISMATCH; /* Opening parenthesis not matched */
2008 }
2009
2010 if (pNumprs->dwInFlags & NUMPRS_USE_ALL && *lpszStr != '\0')
2011 return DISP_E_TYPEMISMATCH; /* Not all chars were consumed */
2012
2013 if (!pNumprs->cDig)
2014 return DISP_E_TYPEMISMATCH; /* No Number found */
2015
2016 pNumprs->cchUsed = cchUsed;
2017 return S_OK;
2018}
#define is_digit(c)
Definition: astoll.c:39
WCHAR OLECHAR
Definition: compat.h:2292
_ACRTIMP int __cdecl wcsncmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:523
#define debugstr_w
Definition: kernel32.h:32
#define NUMPRS_USE_ALL
Definition: oleauto.h:747
#define NUMPRS_LEADING_WHITE
Definition: oleauto.h:735
#define NUMPRS_EXPONENT
Definition: oleauto.h:746
#define NUMPRS_HEX_OCT
Definition: oleauto.h:741
#define NUMPRS_TRAILING_WHITE
Definition: oleauto.h:736
#define NUMPRS_CURRENCY
Definition: oleauto.h:745
#define NUMPRS_TRAILING_MINUS
Definition: oleauto.h:740
#define NUMPRS_LEADING_PLUS
Definition: oleauto.h:737
#define NUMPRS_THOUSANDS
Definition: oleauto.h:744
#define NUMPRS_LEADING_MINUS
Definition: oleauto.h:739
#define NUMPRS_DECIMAL
Definition: oleauto.h:743
#define NUMPRS_INEXACT
Definition: oleauto.h:750
#define NUMPRS_PARENS
Definition: oleauto.h:742
#define NUMPRS_TRAILING_PLUS
Definition: oleauto.h:738
#define iswspace(_c)
Definition: ctype.h:669
ULONG dwInFlags
Definition: oleauto.h:728
INT cchUsed
Definition: oleauto.h:730
#define B_LEADING_ZERO
Definition: variant.c:1539
#define B_INEXACT_ZEROS
Definition: variant.c:1538
#define B_NEGATIVE_EXPONENT
Definition: variant.c:1536
#define B_PROCESSING_OCT
Definition: variant.c:1541
static void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS *lpChars, LCID lcid, DWORD dwFlags)
Definition: variant.c:1508
#define B_PROCESSING_HEX
Definition: variant.c:1540
#define B_EXPONENT_START
Definition: variant.c:1537
#define B_PROCESSING_EXPONENT
Definition: variant.c:1535

Referenced by VARIANT_FormatNumber(), VARIANT_NumberFromBstr(), and wconvert_str().

◆ VarPow()

HRESULT WINAPI VarPow ( LPVARIANT  left,
LPVARIANT  right,
LPVARIANT  result 
)

Definition at line 5639 of file variant.c.

5640{
5641 HRESULT hr = S_OK;
5642 VARIANT dl,dr;
5643 VARTYPE resvt = VT_EMPTY;
5644 VARTYPE leftvt,rightvt;
5645 VARTYPE rightExtraFlags,leftExtraFlags,ExtraFlags;
5646 VARIANT tempLeft, tempRight;
5647
5649
5650 VariantInit(&dl);
5651 VariantInit(&dr);
5652 VariantInit(&tempLeft);
5653 VariantInit(&tempRight);
5654
5655 /* Handle VT_DISPATCH by storing and taking address of returned value */
5656 if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
5657 {
5658 hr = VARIANT_FetchDispatchValue(left, &tempLeft);
5659 if (FAILED(hr)) goto end;
5660 left = &tempLeft;
5661 }
5662 if ((V_VT(right) & VT_TYPEMASK) == VT_DISPATCH)
5663 {
5664 hr = VARIANT_FetchDispatchValue(right, &tempRight);
5665 if (FAILED(hr)) goto end;
5666 right = &tempRight;
5667 }
5668
5669 leftvt = V_VT(left)&VT_TYPEMASK;
5670 rightvt = V_VT(right)&VT_TYPEMASK;
5671 leftExtraFlags = V_VT(left)&(~VT_TYPEMASK);
5672 rightExtraFlags = V_VT(right)&(~VT_TYPEMASK);
5673
5674 if (leftExtraFlags != rightExtraFlags)
5675 {
5677 goto end;
5678 }
5679 ExtraFlags = leftExtraFlags;
5680
5681 /* Native VarPow always returns an error when using extra flags */
5682 if (ExtraFlags != 0)
5683 {
5685 goto end;
5686 }
5687
5688 /* Determine return type */
5689 else if (leftvt == VT_NULL || rightvt == VT_NULL) {
5690 V_VT(result) = VT_NULL;
5691 hr = S_OK;
5692 goto end;
5693 }
5694 else if ((leftvt == VT_EMPTY || leftvt == VT_I2 ||
5695 leftvt == VT_I4 || leftvt == VT_R4 ||
5696 leftvt == VT_R8 || leftvt == VT_CY ||
5697 leftvt == VT_DATE || leftvt == VT_BSTR ||
5698 leftvt == VT_BOOL || leftvt == VT_DECIMAL ||
5699 (leftvt >= VT_I1 && leftvt <= VT_UINT)) &&
5700 (rightvt == VT_EMPTY || rightvt == VT_I2 ||
5701 rightvt == VT_I4 || rightvt == VT_R4 ||
5702 rightvt == VT_R8 || rightvt == VT_CY ||
5703 rightvt == VT_DATE || rightvt == VT_BSTR ||
5704 rightvt == VT_BOOL || rightvt == VT_DECIMAL ||
5705 (rightvt >= VT_I1 && rightvt <= VT_UINT)))
5706 resvt = VT_R8;
5707 else
5708 {
5710 goto end;
5711 }
5712
5713 hr = VariantChangeType(&dl,left,0,resvt);
5714 if (FAILED(hr)) {
5715 ERR("Could not change passed left argument to VT_R8, handle it differently.\n");
5716 hr = E_FAIL;
5717 goto end;
5718 }
5719
5720 hr = VariantChangeType(&dr,right,0,resvt);
5721 if (FAILED(hr)) {
5722 ERR("Could not change passed right argument to VT_R8, handle it differently.\n");
5723 hr = E_FAIL;
5724 goto end;
5725 }
5726
5727 V_VT(result) = VT_R8;
5728 V_R8(result) = pow(V_R8(&dl),V_R8(&dr));
5729
5730end:
5731 VariantClear(&dl);
5732 VariantClear(&dr);
5733 VariantClear(&tempLeft);
5734 VariantClear(&tempRight);
5735
5736 return hr;
5737}
double pow(double x, double y)
Definition: freeldr.c:179

Referenced by interp_exp(), and test_VarPow().

◆ VarRound()

HRESULT WINAPI VarRound ( LPVARIANT  pVarIn,
int  deci,
LPVARIANT  pVarOut 
)

Definition at line 5097 of file variant.c.

5098{
5099 VARIANT varIn;
5100 HRESULT hRet = S_OK;
5101 float factor;
5102 VARIANT temp;
5103
5104 VariantInit(&temp);
5105
5106 TRACE("(%s,%d)\n", debugstr_variant(pVarIn), deci);
5107
5108 /* Handle VT_DISPATCH by storing and taking address of returned value */
5109 if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
5110 {
5111 hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
5112 if (FAILED(hRet)) goto VarRound_Exit;
5113 pVarIn = &temp;
5114 }
5115
5116 switch (V_VT(pVarIn))
5117 {
5118 /* cases that fail on windows */
5119 case VT_I1:
5120 case VT_I8:
5121 case VT_UI2:
5122 case VT_UI4:
5123 hRet = DISP_E_BADVARTYPE;
5124 break;
5125
5126 /* cases just copying in to out */
5127 case VT_UI1:
5128 V_VT(pVarOut) = V_VT(pVarIn);
5129 V_UI1(pVarOut) = V_UI1(pVarIn);
5130 break;
5131 case VT_I2:
5132 V_VT(pVarOut) = V_VT(pVarIn);
5133 V_I2(pVarOut) = V_I2(pVarIn);
5134 break;
5135 case VT_I4:
5136 V_VT(pVarOut) = V_VT(pVarIn);
5137 V_I4(pVarOut) = V_I4(pVarIn);
5138 break;
5139 case VT_NULL:
5140 V_VT(pVarOut) = V_VT(pVarIn);
5141 /* value unchanged */
5142 break;
5143
5144 /* cases that change type */
5145 case VT_EMPTY:
5146 V_VT(pVarOut) = VT_I2;
5147 V_I2(pVarOut) = 0;
5148 break;
5149 case VT_BOOL:
5150 V_VT(pVarOut) = VT_I2;
5151 V_I2(pVarOut) = V_BOOL(pVarIn);
5152 break;
5153 case VT_BSTR:
5154 hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn));
5155 if (FAILED(hRet))
5156 break;
5157 V_VT(&varIn)=VT_R8;
5158 pVarIn = &varIn;
5159 /* Fall through ... */
5160
5161 /* cases we need to do math */
5162 case VT_R8:
5163 if (V_R8(pVarIn)>0) {
5164 V_R8(pVarOut)=floor(V_R8(pVarIn)*pow(10, deci)+0.5)/pow(10, deci);
5165 } else {
5166 V_R8(pVarOut)=ceil(V_R8(pVarIn)*pow(10, deci)-0.5)/pow(10, deci);
5167 }
5168 V_VT(pVarOut) = V_VT(pVarIn);
5169 break;
5170 case VT_R4:
5171 if (V_R4(pVarIn)>0) {
5172 V_R4(pVarOut)=floor(V_R4(pVarIn)*pow(10, deci)+0.5)/pow(10, deci);
5173 } else {
5174 V_R4(pVarOut)=ceil(V_R4(pVarIn)*pow(10, deci)-0.5)/pow(10, deci);
5175 }
5176 V_VT(pVarOut) = V_VT(pVarIn);
5177 break;
5178 case VT_DATE:
5179 if (V_DATE(pVarIn)>0) {
5180 V_DATE(pVarOut)=floor(V_DATE(pVarIn)*pow(10, deci)+0.5)/pow(10, deci);
5181 } else {
5182 V_DATE(pVarOut)=ceil(V_DATE(pVarIn)*pow(10, deci)-0.5)/pow(10, deci);
5183 }
5184 V_VT(pVarOut) = V_VT(pVarIn);
5185 break;
5186 case VT_CY:
5187 if (deci>3)
5188 factor=1;
5189 else
5190 factor=pow(10, 4-deci);
5191
5192 if (V_CY(pVarIn).int64>0) {
5193 V_CY(pVarOut).int64=floor(V_CY(pVarIn).int64/factor)*factor;
5194 } else {
5195 V_CY(pVarOut).int64=ceil(V_CY(pVarIn).int64/factor)*factor;
5196 }
5197 V_VT(pVarOut) = V_VT(pVarIn);
5198 break;
5199 case VT_DECIMAL:
5200 {
5201 double dbl;
5202
5203 hRet = VarR8FromDec(&V_DECIMAL(pVarIn), &dbl);
5204 if (FAILED(hRet))
5205 break;
5206
5207 if (dbl>0.0f)
5208 dbl = floor(dbl*pow(10,deci)+0.5);
5209 else
5210 dbl = ceil(dbl*pow(10,deci)-0.5);
5211
5212 V_VT(pVarOut)=VT_DECIMAL;
5213 hRet = VarDecFromR8(dbl, &V_DECIMAL(pVarOut));
5214 break;
5215 }
5216 /* cases we don't know yet */
5217 default:
5218 FIXME("unimplemented part, V_VT(pVarIn) == 0x%X, deci == %d\n",
5219 V_VT(pVarIn) & VT_TYPEMASK, deci);
5220 hRet = DISP_E_BADVARTYPE;
5221 }
5222VarRound_Exit:
5223 if (FAILED(hRet))
5224 V_VT(pVarOut) = VT_EMPTY;
5226
5227 TRACE("returning %#lx, %s\n", hRet, debugstr_variant(pVarOut));
5228 return hRet;
5229}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint factor
Definition: glfuncs.h:178

Referenced by test_Round(), and test_VarRound().

◆ VarSub()

HRESULT WINAPI VarSub ( LPVARIANT  left,
LPVARIANT  right,
LPVARIANT  result 
)

Definition at line 3747 of file variant.c.

3748{
3749 HRESULT hres = S_OK;
3750 VARTYPE resvt = VT_EMPTY;
3751 VARTYPE leftvt,rightvt;
3752 VARTYPE rightExtraFlags,leftExtraFlags,ExtraFlags;
3753 VARIANT lv,rv;
3754 VARIANT tempLeft, tempRight;
3755
3756 VariantInit(&lv);
3757 VariantInit(&rv);
3758 VariantInit(&tempLeft);
3759 VariantInit(&tempRight);
3760
3762
3763 if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH &&
3764 (V_VT(left)&(~VT_TYPEMASK)) == 0 &&
3765 (V_VT(right) & VT_TYPEMASK) != VT_NULL)
3766 {
3767 if (NULL == V_DISPATCH(left)) {
3768 if ((V_VT(right) & VT_TYPEMASK) >= VT_INT_PTR)
3770 else if ((V_VT(right) & VT_TYPEMASK) >= VT_UI8 &&
3773 else switch (V_VT(right) & VT_TYPEMASK)
3774 {
3775 case VT_VARIANT:
3776 case VT_UNKNOWN:
3777 case 15:
3778 case VT_I1:
3779 case VT_UI2:
3780 case VT_UI4:
3782 }
3783 if (FAILED(hres)) goto end;
3784 }
3785 hres = VARIANT_FetchDispatchValue(left, &tempLeft);
3786 if (FAILED(hres)) goto end;
3787 left = &tempLeft;
3788 }
3789 if ((V_VT(right) & VT_TYPEMASK) == VT_DISPATCH &&
3790 (V_VT(right)&(~VT_TYPEMASK)) == 0 &&
3791 (V_VT(left) & VT_TYPEMASK) != VT_NULL)
3792 {
3793 if (NULL == V_DISPATCH(right))
3794 {
3795 if ((V_VT(left) & VT_TYPEMASK) >= VT_INT_PTR)
3797 else if ((V_VT(left) & VT_TYPEMASK) >= VT_UI8 &&
3800 else switch (V_VT(left) & VT_TYPEMASK)
3801 {
3802 case VT_VARIANT:
3803 case VT_UNKNOWN:
3804 case 15:
3805 case VT_I1:
3806 case VT_UI2:
3807 case VT_UI4:
3809 }
3810 if (FAILED(hres)) goto end;
3811 }
3812 hres = VARIANT_FetchDispatchValue(right, &tempRight);
3813 if (FAILED(hres)) goto end;
3814 right = &tempRight;
3815 }
3816
3817 leftvt = V_VT(left)&VT_TYPEMASK;
3818 rightvt = V_VT(right)&VT_TYPEMASK;
3819 leftExtraFlags = V_VT(left)&(~VT_TYPEMASK);
3820 rightExtraFlags = V_VT(right)&(~VT_TYPEMASK);
3821
3822 if (leftExtraFlags != rightExtraFlags)
3823 {
3825 goto end;
3826 }
3827 ExtraFlags = leftExtraFlags;
3828
3829 /* determine return type and return code */
3830 /* All extra flags produce errors */
3835 ExtraFlags == VT_VECTOR ||
3836 ExtraFlags == VT_BYREF ||
3838 {
3840 goto end;
3841 }
3842 else if (ExtraFlags >= VT_ARRAY)
3843 {
3845 goto end;
3846 }
3847 /* Native VarSub cannot handle: VT_I1, VT_UI2, VT_UI4,
3848 VT_INT, VT_UINT and VT_UI8. Tested with WinXP */
3849 else if (leftvt == VT_CLSID || rightvt == VT_CLSID ||
3850 leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
3851 leftvt == VT_I1 || rightvt == VT_I1 ||
3852 leftvt == VT_UI2 || rightvt == VT_UI2 ||
3853 leftvt == VT_UI4 || rightvt == VT_UI4 ||
3854 leftvt == VT_UI8 || rightvt == VT_UI8 ||
3855 leftvt == VT_INT || rightvt == VT_INT ||
3856 leftvt == VT_UINT || rightvt == VT_UINT ||
3857 leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN ||
3858 leftvt == VT_RECORD || rightvt == VT_RECORD)
3859 {
3860 if (leftvt == VT_RECORD && rightvt == VT_I8)
3862 else if (leftvt < VT_UI1 && rightvt == VT_RECORD)
3864 else if (leftvt >= VT_UI1 && rightvt == VT_RECORD)
3866 else if (leftvt == VT_RECORD && rightvt <= VT_UI1)
3868 else if (leftvt == VT_RECORD && rightvt > VT_UI1)
3870 else
3872 goto end;
3873 }
3874 /* The following flags/types are invalid for left variant */
3875 else if (!((leftvt <= VT_LPWSTR || leftvt == VT_RECORD ||
3876 leftvt == VT_CLSID) && leftvt != (VARTYPE)15 /* undefined vt */ &&
3877 (leftvt < VT_VOID || leftvt > VT_LPWSTR)))
3878 {
3880 goto end;
3881 }
3882 /* The following flags/types are invalid for right variant */
3883 else if (!((rightvt <= VT_LPWSTR || rightvt == VT_RECORD ||
3884 rightvt == VT_CLSID) && rightvt != (VARTYPE)15 /* undefined vt */ &&
3885 (rightvt < VT_VOID || rightvt > VT_LPWSTR)))
3886 {
3888 goto end;
3889 }
3890 else if ((leftvt == VT_NULL && rightvt == VT_DISPATCH) ||
3891 (leftvt == VT_DISPATCH && rightvt == VT_NULL))
3892 resvt = VT_NULL;
3893 else if (leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
3894 leftvt == VT_ERROR || rightvt == VT_ERROR)
3895 {
3897 goto end;
3898 }
3899 else if (leftvt == VT_NULL || rightvt == VT_NULL)
3900 resvt = VT_NULL;
3901 else if ((leftvt == VT_EMPTY && rightvt == VT_BSTR) ||
3902 (leftvt == VT_DATE && rightvt == VT_DATE) ||
3903 (leftvt == VT_BSTR && rightvt == VT_EMPTY) ||
3904 (leftvt == VT_BSTR && rightvt == VT_BSTR))
3905 resvt = VT_R8;
3906 else if (leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
3907 resvt = VT_DECIMAL;
3908 else if (leftvt == VT_DATE || rightvt == VT_DATE)
3909 resvt = VT_DATE;
3910 else if (leftvt == VT_CY || rightvt == VT_CY)
3911 resvt = VT_CY;
3912 else if (leftvt == VT_R8 || rightvt == VT_R8)
3913 resvt = VT_R8;
3914 else if (leftvt == VT_BSTR || rightvt == VT_BSTR)
3915 resvt = VT_R8;
3916 else if (leftvt == VT_R4 || rightvt == VT_R4)
3917 {
3918 if (leftvt == VT_I4 || rightvt == VT_I4 ||
3919 leftvt == VT_I8 || rightvt == VT_I8)
3920 resvt = VT_R8;
3921 else
3922 resvt = VT_R4;
3923 }
3924 else if (leftvt == VT_I8 || rightvt == VT_I8)
3925 resvt = VT_I8;
3926 else if (leftvt == VT_I4 || rightvt == VT_I4)
3927 resvt = VT_I4;
3928 else if (leftvt == VT_I2 || rightvt == VT_I2 ||
3929 leftvt == VT_BOOL || rightvt == VT_BOOL ||
3930 (leftvt == VT_EMPTY && rightvt == VT_EMPTY))
3931 resvt = VT_I2;
3932 else if (leftvt == VT_UI1 || rightvt == VT_UI1)
3933 resvt = VT_UI1;
3934 else
3935 {
3937 goto end;
3938 }
3939
3940 /* coerce to the result type */
3941 if (leftvt == VT_BSTR && rightvt == VT_DATE)
3942 hres = VariantChangeType(&lv, left, 0, VT_R8);
3943 else
3944 hres = VariantChangeType(&lv, left, 0, resvt);
3945 if (hres != S_OK) goto end;
3946 if (leftvt == VT_DATE && rightvt == VT_BSTR)
3947 hres = VariantChangeType(&rv, right, 0, VT_R8);
3948 else
3949 hres = VariantChangeType(&rv, right, 0, resvt);
3950 if (hres != S_OK) goto end;
3951
3952 /* do the math */
3953 V_VT(result) = resvt;
3954 switch (resvt)
3955 {
3956 case VT_NULL:
3957 break;
3958 case VT_DATE:
3959 V_DATE(result) = V_DATE(&lv) - V_DATE(&rv);
3960 break;
3961 case VT_CY:
3962 hres = VarCySub(V_CY(&lv), V_CY(&rv), &(V_CY(result)));
3963 break;
3964 case VT_R4:
3965 V_R4(result) = V_R4(&lv) - V_R4(&rv);
3966 break;
3967 case VT_I8:
3968 V_I8(result) = V_I8(&lv) - V_I8(&rv);
3969 break;
3970 case VT_I4:
3971 V_I4(result) = V_I4(&lv) - V_I4(&rv);
3972 break;
3973 case VT_I2:
3974 V_I2(result) = V_I2(&lv) - V_I2(&rv);
3975 break;
3976 case VT_UI1:
3977 V_UI1(result) = V_UI2(&lv) - V_UI1(&rv);
3978 break;
3979 case VT_R8:
3980 V_R8(result) = V_R8(&lv) - V_R8(&rv);
3981 break;
3982 case VT_DECIMAL:
3983 hres = VarDecSub(&(V_DECIMAL(&lv)), &(V_DECIMAL(&rv)), &(V_DECIMAL(result)));
3984 break;
3985 }
3986
3987end:
3988 VariantClear(&lv);
3989 VariantClear(&rv);
3990 VariantClear(&tempLeft);
3991 VariantClear(&tempRight);
3992 TRACE("returning %#lx, %s\n", hres, debugstr_variant(result));
3993 return hres;
3994}
@ VT_LPWSTR
Definition: compat.h:2325
@ VT_INT_PTR
Definition: compat.h:2327
HRESULT WINAPI VarDecSub(const DECIMAL *pDecLeft, const DECIMAL *pDecRight, DECIMAL *pDecOut)
Definition: vartype.c:5702
HRESULT WINAPI VarCySub(CY cyLeft, CY cyRight, CY *pCyOut)
Definition: vartype.c:3848

Referenced by interp_sub(), and test_VarSub().

◆ VarUdateFromDate()

HRESULT WINAPI VarUdateFromDate ( DATE  dateIn,
ULONG  dwFlags,
UDATE lpUdate 
)

Definition at line 1404 of file variant.c.

1405{
1406 /* Cumulative totals of days per month */
1407 static const USHORT cumulativeDays[] =
1408 {
1409 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
1410 };
1411 double datePart, timePart;
1412 int julianDays;
1413
1414 TRACE("%g, %#lx, %p.\n", dateIn, dwFlags, lpUdate);
1415
1416 if (dateIn <= (DATE_MIN - 1.0) || dateIn >= (DATE_MAX + 1.0))
1417 return E_INVALIDARG;
1418
1419 datePart = dateIn < 0.0 ? ceil(dateIn) : floor(dateIn);
1420 /* Compensate for int truncation (always downwards) */
1421 timePart = fabs(dateIn - datePart) + 0.00000000001;
1422 if (timePart >= 1.0)
1423 timePart -= 0.00000000001;
1424
1425 /* Date */
1426 julianDays = VARIANT_JulianFromDate(dateIn);
1427 VARIANT_DMYFromJulian(julianDays, &lpUdate->st.wYear, &lpUdate->st.wMonth,
1428 &lpUdate->st.wDay);
1429
1430 datePart = (datePart + 1.5) / 7.0;
1431 lpUdate->st.wDayOfWeek = (datePart - floor(datePart)) * 7;
1432 if (lpUdate->st.wDayOfWeek == 0)
1433 lpUdate->st.wDayOfWeek = 5;
1434 else if (lpUdate->st.wDayOfWeek == 1)
1435 lpUdate->st.wDayOfWeek = 6;
1436 else
1437 lpUdate->st.wDayOfWeek -= 2;
1438
1439 if (lpUdate->st.wMonth > 2 && IsLeapYear(lpUdate->st.wYear))
1440 lpUdate->wDayOfYear = 1; /* After February, in a leap year */
1441 else
1442 lpUdate->wDayOfYear = 0;
1443
1444 lpUdate->wDayOfYear += cumulativeDays[lpUdate->st.wMonth];
1445 lpUdate->wDayOfYear += lpUdate->st.wDay;
1446
1447 /* Time */
1448 timePart *= 24.0;
1449 lpUdate->st.wHour = timePart;
1450 timePart -= lpUdate->st.wHour;
1451 timePart *= 60.0;
1452 lpUdate->st.wMinute = timePart;
1453 timePart -= lpUdate->st.wMinute;
1454 timePart *= 60.0;
1455 lpUdate->st.wSecond = timePart;
1456 timePart -= lpUdate->st.wSecond;
1457 lpUdate->st.wMilliseconds = 0;
1458 if (timePart > 0.5)
1459 {
1460 /* Round the milliseconds, adjusting the time/date forward if needed */
1461 if (lpUdate->st.wSecond < 59)
1462 lpUdate->st.wSecond++;
1463 else
1464 {
1465 lpUdate->st.wSecond = 0;
1466 if (lpUdate->st.wMinute < 59)
1467 lpUdate->st.wMinute++;
1468 else
1469 {
1470 lpUdate->st.wMinute = 0;
1471 if (lpUdate->st.wHour < 23)
1472 lpUdate->st.wHour++;
1473 else
1474 {
1475 lpUdate->st.wHour = 0;
1476 /* Roll over a whole day */
1477 if (++lpUdate->st.wDay > 28)
1478 VARIANT_RollUdate(lpUdate);
1479 }
1480 }
1481 }
1482 }
1483 return S_OK;
1484}
_ACRTIMP double __cdecl fabs(double)
if(dx< 0)
Definition: linetemp.h:194
static void VARIANT_DMYFromJulian(int jd, USHORT *year, USHORT *month, USHORT *day)
Definition: variant.c:1048
static int VARIANT_JulianFromDate(int dateIn)
Definition: variant.c:1028
#define DATE_MAX
Definition: variant.h:67

Referenced by test_UdateFromDate(), variant_date_to_number(), VARIANT_FormatDate(), VariantTimeToDosDateTime(), and VariantTimeToSystemTime().

◆ VarXor()

HRESULT WINAPI VarXor ( LPVARIANT  pVarLeft,
LPVARIANT  pVarRight,
LPVARIANT  pVarOut 
)

Definition at line 4612 of file variant.c.

4613{
4614 VARTYPE vt;
4615 VARIANT varLeft, varRight;
4616 VARIANT tempLeft, tempRight;
4617 double d;
4618 HRESULT hRet;
4619
4620 TRACE("(%s,%s,%p)\n", debugstr_variant(pVarLeft), debugstr_variant(pVarRight), pVarOut);
4621
4622 if (V_EXTRA_TYPE(pVarLeft) || V_EXTRA_TYPE(pVarRight) ||
4623 V_VT(pVarLeft) > VT_UINT || V_VT(pVarRight) > VT_UINT ||
4624 V_VT(pVarLeft) == VT_VARIANT || V_VT(pVarRight) == VT_VARIANT ||
4625 V_VT(pVarLeft) == VT_UNKNOWN || V_VT(pVarRight) == VT_UNKNOWN ||
4626 V_VT(pVarLeft) == (VARTYPE)15 || V_VT(pVarRight) == (VARTYPE)15 ||
4627 V_VT(pVarLeft) == VT_ERROR || V_VT(pVarRight) == VT_ERROR)
4628 return DISP_E_BADVARTYPE;
4629
4630 if (V_VT(pVarLeft) == VT_NULL || V_VT(pVarRight) == VT_NULL)
4631 {
4632 /* NULL XOR anything valid is NULL */
4633 V_VT(pVarOut) = VT_NULL;
4634 return S_OK;
4635 }
4636
4637 V_VT(&varLeft) = V_VT(&varRight) = VT_EMPTY;
4638 VariantInit(&tempLeft);
4639 VariantInit(&tempRight);
4640
4641 /* Handle VT_DISPATCH by storing and taking address of returned value */
4642 if ((V_VT(pVarLeft) & VT_TYPEMASK) == VT_DISPATCH)
4643 {
4644 hRet = VARIANT_FetchDispatchValue(pVarLeft, &tempLeft);
4645 if (FAILED(hRet)) goto VarXor_Exit;
4646 pVarLeft = &tempLeft;
4647 }
4648 if ((V_VT(pVarRight) & VT_TYPEMASK) == VT_DISPATCH)
4649 {
4650 hRet = VARIANT_FetchDispatchValue(pVarRight, &tempRight);
4651 if (FAILED(hRet)) goto VarXor_Exit;
4652 pVarRight = &tempRight;
4653 }
4654
4655 /* Copy our inputs so we don't disturb anything */
4656 hRet = VariantCopy(&varLeft, pVarLeft);
4657 if (FAILED(hRet))
4658 goto VarXor_Exit;
4659
4660 hRet = VariantCopy(&varRight, pVarRight);
4661 if (FAILED(hRet))
4662 goto VarXor_Exit;
4663
4664 /* Try any strings first as numbers, then as VT_BOOL */
4665 if (V_VT(&varLeft) == VT_BSTR)
4666 {
4667 hRet = VarR8FromStr(V_BSTR(&varLeft), LOCALE_USER_DEFAULT, 0, &d);
4668 hRet = VariantChangeType(&varLeft, &varLeft, VARIANT_LOCALBOOL,
4669 FAILED(hRet) ? VT_BOOL : VT_I4);
4670 if (FAILED(hRet))
4671 goto VarXor_Exit;
4672 }
4673
4674 if (V_VT(&varRight) == VT_BSTR)
4675 {
4676 hRet = VarR8FromStr(V_BSTR(&varRight), LOCALE_USER_DEFAULT, 0, &d);
4677 hRet = VariantChangeType(&varRight, &varRight, VARIANT_LOCALBOOL,
4678 FAILED(hRet) ? VT_BOOL : VT_I4);
4679 if (FAILED(hRet))
4680 goto VarXor_Exit;
4681 }
4682
4683 /* Determine the result type */
4684 if (V_VT(&varLeft) == VT_I8 || V_VT(&varRight) == VT_I8)
4685 {
4686 if (V_VT(pVarLeft) == VT_INT || V_VT(pVarRight) == VT_INT)
4687 {
4688 hRet = DISP_E_TYPEMISMATCH;
4689 goto VarXor_Exit;
4690 }
4691 vt = VT_I8;
4692 }
4693 else
4694 {
4695 switch ((V_VT(&varLeft) << 16) | V_VT(&varRight))
4696 {
4697 case (VT_BOOL << 16) | VT_BOOL:
4698 vt = VT_BOOL;
4699 break;
4700 case (VT_UI1 << 16) | VT_UI1:
4701 vt = VT_UI1;
4702 break;
4703 case (VT_EMPTY << 16) | VT_EMPTY:
4704 case (VT_EMPTY << 16) | VT_UI1:
4705 case (VT_EMPTY << 16) | VT_I2:
4706 case (VT_EMPTY << 16) | VT_BOOL:
4707 case (VT_UI1 << 16) | VT_EMPTY:
4708 case (VT_UI1 << 16) | VT_I2:
4709 case (VT_UI1 << 16) | VT_BOOL:
4710 case (VT_I2 << 16) | VT_EMPTY:
4711 case (VT_I2 << 16) | VT_UI1:
4712 case (VT_I2 << 16) | VT_I2:
4713 case (VT_I2 << 16) | VT_BOOL:
4714 case (VT_BOOL << 16) | VT_EMPTY:
4715 case (VT_BOOL << 16) | VT_UI1:
4716 case (VT_BOOL << 16) | VT_I2:
4717 vt = VT_I2;
4718 break;
4719 default:
4720 vt = VT_I4;
4721 break;
4722 }
4723 }
4724
4725 /* VT_UI4 does not overflow */
4726 if (vt != VT_I8)
4727 {
4728 if (V_VT(&varLeft) == VT_UI4)
4729 V_VT(&varLeft) = VT_I4;
4730 if (V_VT(&varRight) == VT_UI4)
4731 V_VT(&varRight) = VT_I4;
4732 }
4733
4734 /* Convert our input copies to the result type */
4735 if (V_VT(&varLeft) != vt)
4736 hRet = VariantChangeType(&varLeft, &varLeft, 0, vt);
4737 if (FAILED(hRet))
4738 goto VarXor_Exit;
4739
4740 if (V_VT(&varRight) != vt)
4741 hRet = VariantChangeType(&varRight, &varRight, 0, vt);
4742 if (FAILED(hRet))
4743 goto VarXor_Exit;
4744
4745 V_VT(pVarOut) = vt;
4746
4747 /* Calculate the result */
4748 switch (vt)
4749 {
4750 case VT_I8:
4751 V_I8(pVarOut) = V_I8(&varLeft) ^ V_I8(&varRight);
4752 break;
4753 case VT_I4:
4754 V_I4(pVarOut) = V_I4(&varLeft) ^ V_I4(&varRight);
4755 break;
4756 case VT_BOOL:
4757 case VT_I2:
4758 V_I2(pVarOut) = V_I2(&varLeft) ^ V_I2(&varRight);
4759 break;
4760 case VT_UI1:
4761 V_UI1(pVarOut) = V_UI1(&varLeft) ^ V_UI1(&varRight);
4762 break;
4763 }
4764
4765VarXor_Exit:
4766 VariantClear(&varLeft);
4767 VariantClear(&varRight);
4768 VariantClear(&tempLeft);
4769 VariantClear(&tempRight);
4770 return hRet;
4771}

Referenced by interp_xor(), test_VarXor(), and VarEqv().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( variant  )