Hi,
Part 5 of oleaut32 updates.
Cheers,
Jon
License: X11
Changelog:
Jon Griffiths <jon_p_griffiths@yahoo.com>
+dlls/oleaut32/cy.c dlls/oleaut32/Makefile.in
dlls/oleaut32/oleaut32.spec
dlls/oleaut32/variant.c
Implement/document currency low-level calls
__________________________________
Do you Yahoo!?
The New Yahoo! Shopping - with improved product search
http://shopping.yahoo.com
diff -uP --minimal wine-diff/dlls/oleaut32/cy.c wine-develop/dlls/oleaut32/cy.c
--- wine-diff/dlls/oleaut32/cy.c 1970-01-01 01:00:00.000000000 +0100
+++ wine-develop/dlls/oleaut32/cy.c 2003-10-06 19:20:30.000000000 +0100
@@ -0,0 +1,701 @@
+/*
+ * Variant VT_CY (Currency) Functions
+ *
+ * Copyright 2003 Jon Griffiths
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include "wine/debug.h"
+#include "winbase.h"
+#include "variant.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ole);
+
+/* Powers of 10 from 0..4 D.P. */
+static const int CY_Divisors[5] = { CY_MULTIPLIER/10000, CY_MULTIPLIER/1000,
+ CY_MULTIPLIER/100, CY_MULTIPLIER/10, CY_MULTIPLIER };
+
+/************************************************************************
+ * VarCyFromUI1 (OLEAUT32.98)
+ *
+ * Convert a VT_UI1 to a VT_CY.
+ *
+ * PARAMS
+ * bIn [I] Source
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_INVALIDARG, if the source value is invalid
+ * DISP_E_OVERFLOW, if the value will not fit in the destination
+ * DISP_E_TYPEMISMATCH, if the type cannot be converted
+ */
+HRESULT WINAPI VarCyFromUI1(BYTE bIn, CY* pCyOut)
+{
+ return _VarCyFromUI1(bIn, pCyOut);
+}
+
+/************************************************************************
+ * VarCyFromI2 (OLEAUT32.99)
+ *
+ * Convert a VT_I2 to a VT_CY.
+ *
+ * PARAMS
+ * sIn [I] Source
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_INVALIDARG, if the source value is invalid
+ * DISP_E_OVERFLOW, if the value will not fit in the destination
+ * DISP_E_TYPEMISMATCH, if the type cannot be converted
+ */
+HRESULT WINAPI VarCyFromI2(SHORT sIn, CY* pCyOut)
+{
+ return _VarCyFromI2(sIn, pCyOut);
+}
+
+/************************************************************************
+ * VarCyFromI4 (OLEAUT32.100)
+ *
+ * Convert a VT_I4 to a VT_CY.
+ *
+ * PARAMS
+ * sIn [I] Source
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_INVALIDARG, if the source value is invalid
+ * DISP_E_OVERFLOW, if the value will not fit in the destination
+ * DISP_E_TYPEMISMATCH, if the type cannot be converted
+ */
+HRESULT WINAPI VarCyFromI4(LONG lIn, CY* pCyOut)
+{
+ return _VarCyFromI4(lIn, pCyOut);
+}
+
+/************************************************************************
+ * VarCyFromR4 (OLEAUT32.101)
+ *
+ * Convert a VT_R4 to a VT_CY.
+ *
+ * PARAMS
+ * fltIn [I] Source
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_INVALIDARG, if the source value is invalid
+ * DISP_E_OVERFLOW, if the value will not fit in the destination
+ * DISP_E_TYPEMISMATCH, if the type cannot be converted
+ */
+HRESULT WINAPI VarCyFromR4(FLOAT fltIn, CY* pCyOut)
+{
+ return _VarCyFromR4(fltIn, pCyOut);
+}
+
+/************************************************************************
+ * VarCyFromR8 (OLEAUT32.102)
+ *
+ * Convert a VT_R8 to a VT_CY.
+ *
+ * PARAMS
+ * dblIn [I] Source
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_INVALIDARG, if the source value is invalid
+ * DISP_E_OVERFLOW, if the value will not fit in the destination
+ * DISP_E_TYPEMISMATCH, if the type cannot be converted
+ */
+HRESULT WINAPI VarCyFromR8(double dblIn, CY* pCyOut)
+{
+#if defined(__GNUC__) && defined(__i386__)
+ /* This code gives identical results to Win32 on Intel.
+ * Here we use fp exceptions to catch overflows when storing the value.
+ */
+ static const unsigned short r8_fpcontrol = 0x137f;
+ static const double r8_multiplier = CY_MULTIPLIER_F;
+ unsigned short old_fpcontrol, result_fpstatus;
+
+ /* Clear exceptions, save the old fp state and load the new state */
+ __asm__ __volatile__( "fnclex" );
+ __asm__ __volatile__( "fstcw %0" : "=m" (old_fpcontrol) : );
+ __asm__ __volatile__( "fldcw %0" : : "m" (r8_fpcontrol) );
+ /* Perform the conversion. */
+ __asm__ __volatile__( "fldl %0" : : "m" (dblIn) );
+ __asm__ __volatile__( "fmull %0" : : "m" (r8_multiplier) );
+ __asm__ __volatile__( "fistpll %0" : : "m" (*pCyOut) );
+ /* Save the resulting fp state, load the old state and clear exceptions */
+ __asm__ __volatile__( "fstsw %0" : "=m" (result_fpstatus) : );
+ __asm__ __volatile__( "fnclex" );
+ __asm__ __volatile__( "fldcw %0" : : "m" (old_fpcontrol) );
+
+ if (result_fpstatus & 0x9) /* Overflow | Invalid */
+ return DISP_E_OVERFLOW;
+ return S_OK;
+#else
+ /* This version produces slightly different results for boundary cases */
+ if (dblIn < -922337203685477.5807 || dblIn >= 922337203685477.5807)
+ return DISP_E_OVERFLOW;
+ dblIn *= CY_MULTIPLIER_F;
+ OLEAUT32_DutchRound(LONG64, dblIn, pCyOut->int64);
+#endif
+ return S_OK;
+}
+
+/************************************************************************
+ * VarCyFromDate (OLEAUT32.103)
+ *
+ * Convert a VT_DATE to a VT_CY.
+ *
+ * PARAMS
+ * dateIn [I] Source
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_INVALIDARG, if the source value is invalid
+ * DISP_E_OVERFLOW, if the value will not fit in the destination
+ * DISP_E_TYPEMISMATCH, if the type cannot be converted
+ */
+HRESULT WINAPI VarCyFromDate(DATE dateIn, CY* pCyOut)
+{
+ return _VarCyFromDate(dateIn, pCyOut);
+}
+
+/************************************************************************
+ * VarCyFromStr (OLEAUT32.104)
+ *
+ * Convert a VT_BSTR to a VT_CY.
+ *
+ * PARAMS
+ * strIn [I] Source
+ * lcid [I] LCID for the conversion
+ * dwFlags [I] VAR_ flags from "oleauto.h"
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_INVALIDARG, if the source value is invalid
+ * DISP_E_OVERFLOW, if the value will not fit in the destination
+ * DISP_E_TYPEMISMATCH, if the type cannot be converted
+ */
+HRESULT WINAPI VarCyFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, CY* pCyOut)
+{
+ return _VarCyFromStr(strIn, lcid, dwFlags, pCyOut);
+}
+
+/************************************************************************
+ * VarCyFromDisp (OLEAUT32.105)
+ *
+ * Convert a VT_DISPATCH to a VT_CY.
+ *
+ * PARAMS
+ * pdispIn [I] Source
+ * lcid [I] LCID for conversion
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_INVALIDARG, if the source value is invalid
+ * DISP_E_OVERFLOW, if the value will not fit in the destination
+ * DISP_E_TYPEMISMATCH, if the type cannot be converted
+ */
+HRESULT WINAPI VarCyFromDisp(IDispatch* pdispIn, LCID lcid, CY* pCyOut)
+{
+ return _VarCyFromDisp(pdispIn, lcid, pCyOut);
+}
+
+/************************************************************************
+ * VarCyFromBool (OLEAUT32.106)
+ *
+ * Convert a VT_BOOL to a VT_CY.
+ *
+ * PARAMS
+ * boolIn [I] Source
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_INVALIDARG, if the source value is invalid
+ * DISP_E_OVERFLOW, if the value will not fit in the destination
+ * DISP_E_TYPEMISMATCH, if the type cannot be converted
+ *
+ * NOTES
+ * While the sign of the boolean is stored in the currency, the value is
+ * converted to either 0 or 1.
+ */
+HRESULT WINAPI VarCyFromBool(VARIANT_BOOL boolIn, CY* pCyOut)
+{
+ return _VarCyFromBool(boolIn, pCyOut);
+}
+
+/************************************************************************
+ * VarCyFromI1 (OLEAUT32.225)
+ *
+ * Convert a VT_I1 to a VT_CY.
+ *
+ * PARAMS
+ * cIn [I] Source
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_INVALIDARG, if the source value is invalid
+ * DISP_E_OVERFLOW, if the value will not fit in the destination
+ * DISP_E_TYPEMISMATCH, if the type cannot be converted
+ */
+HRESULT WINAPI VarCyFromI1(signed char cIn, CY* pCyOut)
+{
+ return _VarCyFromI1(cIn, pCyOut);
+}
+
+/************************************************************************
+ * VarCyFromUI2 (OLEAUT32.226)
+ *
+ * Convert a VT_UI2 to a VT_CY.
+ *
+ * PARAMS
+ * usIn [I] Source
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_INVALIDARG, if the source value is invalid
+ * DISP_E_OVERFLOW, if the value will not fit in the destination
+ * DISP_E_TYPEMISMATCH, if the type cannot be converted
+ */
+HRESULT WINAPI VarCyFromUI2(USHORT usIn, CY* pCyOut)
+{
+ return _VarCyFromUI2(usIn, pCyOut);
+}
+
+/************************************************************************
+ * VarCyFromUI4 (OLEAUT32.227)
+ *
+ * Convert a VT_UI4 to a VT_CY.
+ *
+ * PARAMS
+ * ulIn [I] Source
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_INVALIDARG, if the source value is invalid
+ * DISP_E_OVERFLOW, if the value will not fit in the destination
+ * DISP_E_TYPEMISMATCH, if the type cannot be converted
+ */
+HRESULT WINAPI VarCyFromUI4(ULONG ulIn, CY* pCyOut)
+{
+ return _VarCyFromUI4(ulIn, pCyOut);
+}
+
+/************************************************************************
+ * VarCyFromDec (OLEAUT32.228)
+ *
+ * Convert a VT_DECIMAL to a VT_CY.
+ *
+ * PARAMS
+ * pdecIn [I] Source
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_INVALIDARG, if the source value is invalid
+ * DISP_E_OVERFLOW, if the value will not fit in the destination
+ * DISP_E_TYPEMISMATCH, if the type cannot be converted
+ */
+HRESULT WINAPI VarCyFromDec(DECIMAL* pdecIn, CY* pCyOut)
+{
+ DECIMAL rounded;
+ HRESULT hRet;
+
+ hRet = VarDecRound(pdecIn, 4, &rounded);
+
+ if (SUCCEEDED(hRet))
+ {
+ double d;
+
+ if (DEC_HI32(&rounded))
+ return DISP_E_OVERFLOW;
+
+ /* Note: Without the casts this promotes to int64 which loses precision */
+ d = (double)DEC_LO64(&rounded) / (double)CY_Divisors[DEC_SCALE(&rounded)];
+ if (DEC_SIGN(&rounded))
+ d = -d;
+ return _VarCyFromR8(d, pCyOut);
+ }
+ return hRet;
+}
+
+/************************************************************************
+ * VarCyFromI8 (OLEAUT32.366)
+ *
+ * Convert a VT_I8 to a VT_CY.
+ *
+ * PARAMS
+ * ullIn [I] Source
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_INVALIDARG, if the source value is invalid
+ * DISP_E_OVERFLOW, if the value will not fit in the destination
+ * DISP_E_TYPEMISMATCH, if the type cannot be converted
+ */
+HRESULT WINAPI VarCyFromI8(LONG64 llIn, CY* pCyOut)
+{
+ return _VarCyFromI8(llIn, pCyOut);
+}
+
+/************************************************************************
+ * VarCyFromUI8 (OLEAUT32.375)
+ *
+ * Convert a VT_UI8 to a VT_CY.
+ *
+ * PARAMS
+ * ullIn [I] Source
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: E_INVALIDARG, if the source value is invalid
+ * DISP_E_OVERFLOW, if the value will not fit in the destination
+ * DISP_E_TYPEMISMATCH, if the type cannot be converted
+ */
+HRESULT WINAPI VarCyFromUI8(ULONG64 ullIn, CY* pCyOut)
+{
+ return _VarCyFromUI8(ullIn, pCyOut);
+}
+
+/************************************************************************
+ * VarCyAdd (OLEAUT32.299)
+ *
+ * Add one CY to another.
+ *
+ * PARAMS
+ * cyLeft [I] Source
+ * cyRight [I] Value to add
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
+ */
+HRESULT WINAPI VarCyAdd(const CY cyLeft, const CY cyRight, CY* pCyOut)
+{
+ double l,r;
+ _VarR8FromCy(cyLeft, &l);
+ _VarR8FromCy(cyRight, &r);
+ l = l + r;
+ return _VarCyFromR8(l, pCyOut);
+}
+
+/************************************************************************
+ * VarCyMul (OLEAUT32.303)
+ *
+ * Multiply one CY by another.
+ *
+ * PARAMS
+ * cyLeft [I] Source
+ * cyRight [I] Value to multiply by
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
+ */
+HRESULT WINAPI VarCyMul(const CY cyLeft, const CY cyRight, CY* pCyOut)
+{
+ double l,r;
+ _VarR8FromCy(cyLeft, &l);
+ _VarR8FromCy(cyRight, &r);
+ l = l * r;
+ return _VarCyFromR8(l, pCyOut);
+}
+
+/************************************************************************
+ * VarCyMulI4 (OLEAUT32.304)
+ *
+ * Multiply one CY by a VT_I4.
+ *
+ * PARAMS
+ * cyLeft [I] Source
+ * lRight [I] Value to multiply by
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
+ */
+HRESULT WINAPI VarCyMulI4(const CY cyLeft, LONG lRight, CY* pCyOut)
+{
+ double d;
+
+ _VarR8FromCy(cyLeft, &d);
+ d = d * lRight;
+ return _VarCyFromR8(d, pCyOut);
+}
+
+/************************************************************************
+ * VarCySub (OLEAUT32.305)
+ *
+ * Subtract one CY from another.
+ *
+ * PARAMS
+ * cyLeft [I] Source
+ * cyRight [I] Value to subtract
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
+ */
+HRESULT WINAPI VarCySub(const CY cyLeft, const CY cyRight, CY* pCyOut)
+{
+ double l,r;
+ _VarR8FromCy(cyLeft, &l);
+ _VarR8FromCy(cyRight, &r);
+ l = l - r;
+ return _VarCyFromR8(l, pCyOut);
+}
+
+/************************************************************************
+ * VarCyAbs (OLEAUT32.306)
+ *
+ * Convert a VT_CY into its absolute value.
+ *
+ * PARAMS
+ * cyIn [I] Source
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK. pCyOut contains the absolute value.
+ * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
+ */
+HRESULT WINAPI VarCyAbs(const CY cyIn, CY* pCyOut)
+{
+ if (cyIn.s.Hi == (int)0x80000000 && !cyIn.s.Lo)
+ return DISP_E_OVERFLOW;
+
+ pCyOut->int64 = cyIn.int64 < 0 ? -cyIn.int64 : cyIn.int64;
+ return S_OK;
+}
+
+/************************************************************************
+ * VarCyFix (OLEAUT32.307)
+ *
+ * Return the integer part of a VT_CY.
+ *
+ * PARAMS
+ * cyIn [I] Source
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
+ */
+HRESULT WINAPI VarCyFix(const CY cyIn, CY* pCyOut)
+{
+ pCyOut->int64 = cyIn.int64 / CY_MULTIPLIER;
+ pCyOut->int64 *= CY_MULTIPLIER;
+ return S_OK;
+}
+
+/************************************************************************
+ * VarCyInt (OLEAUT32.308)
+ *
+ * Return the integer part of a VT_CY.
+ *
+ * PARAMS
+ * cyIn [I] Source
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
+ */
+HRESULT WINAPI VarCyInt(const CY cyIn, CY* pCyOut)
+{
+ double d;
+
+ _VarR8FromCy(cyIn, &d);
+ d = floor(d) * CY_MULTIPLIER_F;
+ OLEAUT32_DutchRound(LONGLONG, d, pCyOut->int64);
+ return S_OK;
+}
+
+/************************************************************************
+ * VarCyNeg (OLEAUT32.309)
+ *
+ * Change the sign of a VT_CY.
+ *
+ * PARAMS
+ * cyIn [I] Source
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
+ */
+HRESULT WINAPI VarCyNeg(const CY cyIn, CY* pCyOut)
+{
+ if (cyIn.s.Hi == (int)0x80000000 && !cyIn.s.Lo)
+ return DISP_E_OVERFLOW;
+
+ pCyOut->int64 = -cyIn.int64;
+ return S_OK;
+}
+
+/************************************************************************
+ * VarCyRound (OLEAUT32.310)
+ *
+ * Change the precision of a VT_CY.
+ *
+ * PARAMS
+ * cyIn [I] Source
+ * cDecimals [I] New number of decimals to keep
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
+ */
+HRESULT WINAPI VarCyRound(const CY cyIn, int cDecimals, CY* pCyOut)
+{
+ if (cDecimals < 0)
+ return E_INVALIDARG;
+
+ if (cDecimals > 3)
+ {
+ /* Rounding to more precision than we have */
+ *pCyOut = cyIn;
+ return S_OK;
+ }
+ else
+ {
+ double d, div = CY_Divisors[cDecimals];
+
+ _VarR8FromCy(cyIn, &d);
+ d = d * div;
+ OLEAUT32_DutchRound(LONGLONG, d, pCyOut->int64)
+ d = (double)pCyOut->int64 / div * CY_MULTIPLIER_F;
+ OLEAUT32_DutchRound(LONGLONG, d, pCyOut->int64)
+ return S_OK;
+ }
+}
+
+/************************************************************************
+ * VarCyCmp (OLEAUT32.311)
+ *
+ * Compare two VT_CY values.
+ *
+ * PARAMS
+ * cyLeft [I] Source
+ * cyRight [I] Value to compare
+ *
+ * RETURNS
+ * Success: VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that the value to
+ * compare is less, equal or greater than source respectively.
+ * Failure: DISP_E_OVERFLOW, if overflow occurs during the comparason
+ */
+HRESULT WINAPI VarCyCmp(const CY cyLeft, const CY cyRight)
+{
+ HRESULT hRet;
+ CY result;
+
+ /* Subtract right from left, and compare the result to 0 */
+ hRet = VarCySub(cyLeft, cyRight, &result);
+
+ if (SUCCEEDED(hRet))
+ {
+ if (result.int64 < 0)
+ hRet = (HRESULT)VARCMP_LT;
+ else if (result.int64 > 0)
+ hRet = (HRESULT)VARCMP_GT;
+ else
+ hRet = (HRESULT)VARCMP_EQ;
+ }
+ return hRet;
+}
+
+/************************************************************************
+ * VarCyCmpR8 (OLEAUT32.312)
+ *
+ * Compare a VT_CY to a double
+ *
+ * PARAMS
+ * cyLeft [I] Currency Source
+ * dblRight [I] double to compare to cyLeft
+ *
+ * RETURNS
+ * Success: VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that dblRight is
+ * less than, equal to or greater than cyLeft respectively.
+ * Failure: DISP_E_OVERFLOW, if overflow occurs during the comparason
+ */
+HRESULT WINAPI VarCyCmpR8(const CY cyLeft, double dblRight)
+{
+ HRESULT hRet;
+ CY cyRight;
+
+ hRet = _VarCyFromR8(dblRight, &cyRight);
+
+ if (SUCCEEDED(hRet))
+ hRet = VarCyCmp(cyLeft, cyRight);
+
+ return hRet;
+}
+
+/************************************************************************
+ * VarCyMulI8 (OLEAUT32.329)
+ *
+ * Multiply a VT_CY by a VT_I8.
+ *
+ * PARAMS
+ * cyLeft [I] Source
+ * llRight [I] Value to multiply by
+ * pCyOut [O] Destination
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
+ */
+HRESULT WINAPI VarCyMulI8(const CY cyLeft, LONG64 llRight, CY* pCyOut)
+{
+ double d;
+
+ _VarR8FromCy(cyLeft, &d);
+ d = d * (double)llRight;
+ return _VarCyFromR8(d, pCyOut);
+}
+
+/**********************************************************************
+ * VarFormatCurrency [OLEAUT32.127]
+ */
+HRESULT WINAPI VarFormatCurrency(LPVARIANT pVarIn, INT iNumDigits, INT lead,
+ INT paren, INT group, ULONG dwFlags, BSTR *pBstrOut)
+{
+ FIXME("%p %d %d %d %d %lx %p\n", pVarIn, iNumDigits, lead, paren, group, dwFlags, pBstrOut);
+
+ if (!pVarIn || V_VT(pVarIn) == VT_BYREF || !pBstrOut || iNumDigits > 255)
+ return E_INVALIDARG;
+
+ return E_NOTIMPL;
+}
diff -uP --minimal wine-diff/dlls/oleaut32/Makefile.in wine-develop/dlls/oleaut32/Makefile.in
--- wine-diff/dlls/oleaut32/Makefile.in 2003-10-06 19:06:09.000000000 +0100
+++ wine-develop/dlls/oleaut32/Makefile.in 2003-10-06 19:12:26.000000000 +0100
@@ -16,6 +16,7 @@
C_SRCS = \
connpt.c \
+ cy.c \
dispatch.c \
dec.c \
hash.c \
--- wine-diff/dlls/oleaut32/oleaut32.spec 2003-10-06 19:06:09.000000000 +0100
+++ wine-develop/dlls/oleaut32/oleaut32.spec 2003-10-06 19:18:21.000000000 +0100
@@ -101,8 +101,8 @@
101 stdcall VarCyFromR4(long ptr)
102 stdcall VarCyFromR8(double ptr)
103 stdcall VarCyFromDate(double ptr)
-104 stdcall VarCyFromStr(ptr long long ptr)
-105 stub VarCyFromDisp
+104 stdcall VarCyFromStr(wstr long long ptr)
+105 stdcall VarCyFromDisp(ptr long ptr)
106 stdcall VarCyFromBool(long ptr)
107 stub VarFormatNumber # stdcall (ptr long long long long long ptr)
108 stdcall VarBstrFromUI1(long long long ptr)
@@ -223,7 +223,7 @@
225 stdcall VarCyFromI1(long ptr)
226 stdcall VarCyFromUI2(long ptr)
227 stdcall VarCyFromUI4(long ptr)
-228 stub VarCyFromDec
+228 stdcall VarCyFromDec(ptr ptr)
229 stdcall VarBstrFromI1(long long long ptr)
230 stdcall VarBstrFromUI2(long long long ptr)
231 stdcall VarBstrFromUI4(long long long ptr)
@@ -294,17 +294,17 @@
296 stub LPSAFEARRAY_Marshal
297 stub LPSAFEARRAY_Unmarshal
298 stdcall VarDecCmpR8(ptr double)
-299 stub VarCyAdd
-303 stub VarCyMul
-304 stdcall VarCyMulI4(double long ptr)
-305 stub VarCySub
-306 stub VarCyAbs
-307 stub VarCyFix
-308 stub VarCyInt
-309 stub VarCyNeg
-310 stub VarCyRound
-311 stub VarCyCmp
-312 stub VarCyCmpR8
+299 stdcall VarCyAdd(long long long long ptr)
+303 stdcall VarCyMul(long long long long ptr)
+304 stdcall VarCyMulI4(long long long ptr)
+305 stdcall VarCySub(long long long long ptr)
+306 stdcall VarCyAbs(long long ptr)
+307 stdcall VarCyFix(long long ptr)
+308 stdcall VarCyInt(long long ptr)
+309 stdcall VarCyNeg(long long ptr)
+310 stdcall VarCyRound(long long long ptr)
+311 stdcall VarCyCmp(long long long long)
+312 stdcall VarCyCmpR8(long long double)
313 stdcall VarBstrCat(wstr wstr ptr)
314 stdcall VarBstrCmp(wstr wstr long long)
315 stub VarR8Pow # stdcall (double double ptr)
@@ -319,7 +319,7 @@
325 stub SetVarConversionLocaleSetting
326 stub GetVarConversionLocaleSetting
327 stdcall SetOaNoCache()
-329 stub VarCyMulI8
+329 stdcall VarCyMulI8(long long long long ptr)
330 stdcall VarDateFromUdate(ptr long ptr)
331 stdcall VarUdateFromDate(double long ptr)
332 stub GetAltMonthNames
@@ -346,8 +346,8 @@
363 stdcall VarR8FromUI8(long long ptr)
364 stub VarDateFromI8
365 stub VarDateFromUI8
-366 stub VarCyFromI8
-367 stub VarCyFromUI8
+366 stdcall VarCyFromI8(long long ptr)
+367 stdcall VarCyFromUI8(long long ptr)
368 stub VarBstrFromI8
369 stub VarBstrFromUI8
370 stub VarBoolFromI8
diff -uP --minimal wine-diff/dlls/oleaut32/variant.c wine-develop/dlls/oleaut32/variant.c
--- wine-diff/dlls/oleaut32/variant.c 2003-10-06 19:06:09.000000000 +0100
+++ wine-develop/dlls/oleaut32/variant.c 2003-10-06 19:20:19.000000000 +0100
@@ -2745,139 +2745,6 @@
}
/**********************************************************************
- * VarCyFromUI1 [OLEAUT32.98]
- * Convert unsigned char to currency
- */
-HRESULT WINAPI VarCyFromUI1(BYTE bIn, CY* pcyOut) {
- pcyOut->s.Hi = 0;
- pcyOut->s.Lo = ((ULONG)bIn) * 10000;
-
- return S_OK;
-}
-
-/**********************************************************************
- * VarCyFromI2 [OLEAUT32.99]
- * Convert signed short to currency
- */
-HRESULT WINAPI VarCyFromI2(short sIn, CY* pcyOut) {
- if (sIn < 0) pcyOut->s.Hi = -1;
- else pcyOut->s.Hi = 0;
- pcyOut->s.Lo = ((ULONG)sIn) * 10000;
-
- return S_OK;
-}
-
-/**********************************************************************
- * VarCyFromI4 [OLEAUT32.100]
- * Convert signed long to currency
- */
-HRESULT WINAPI VarCyFromI4(LONG lIn, CY* pcyOut) {
- double t = (double)lIn * (double)10000;
- pcyOut->s.Hi = (LONG)(t / (double)4294967296.0);
- pcyOut->s.Lo = (ULONG)fmod(t, (double)4294967296.0);
- if (lIn < 0) pcyOut->s.Hi--;
-
- return S_OK;
-}
-
-/**********************************************************************
- * VarCyFromR4 [OLEAUT32.101]
- * Convert float to currency
- */
-HRESULT WINAPI VarCyFromR4(FLOAT fltIn, CY* pcyOut) {
- double t = round((double)fltIn * (double)10000);
- pcyOut->s.Hi = (LONG)(t / (double)4294967296.0);
- pcyOut->s.Lo = (ULONG)fmod(t, (double)4294967296.0);
- if (fltIn < 0) pcyOut->s.Hi--;
-
- return S_OK;
-}
-
-/**********************************************************************
- * VarCyFromR8 [OLEAUT32.102]
- * Convert double to currency
- */
-HRESULT WINAPI VarCyFromR8(double dblIn, CY* pcyOut) {
- double t = round(dblIn * (double)10000);
- pcyOut->s.Hi = (LONG)(t / (double)4294967296.0);
- pcyOut->s.Lo = (ULONG)fmod(t, (double)4294967296.0);
- if (dblIn < 0) pcyOut->s.Hi--;
-
- return S_OK;
-}
-
-/**********************************************************************
- * VarCyFromDate [OLEAUT32.103]
- * Convert date to currency
- */
-HRESULT WINAPI VarCyFromDate(DATE dateIn, CY* pcyOut) {
- double t = round((double)dateIn * (double)10000);
- pcyOut->s.Hi = (LONG)(t / (double)4294967296.0);
- pcyOut->s.Lo = (ULONG)fmod(t, (double)4294967296.0);
- if (dateIn < 0) pcyOut->s.Hi--;
-
- return S_OK;
-}
-
-/**********************************************************************
- * VarCyFromStr [OLEAUT32.104]
- * FIXME: Never tested with decimal separator other than '.'
- */
-HRESULT WINAPI VarCyFromStr(OLECHAR *strIn, LCID lcid, ULONG dwFlags, CY *pcyOut)
-{
- TRACE("(%s, 0x%08lx, 0x%08lx, %p)\n", debugstr_w(strIn), lcid, dwFlags, pcyOut);
- return _VarCyFromStr(strIn, lcid, dwFlags, pcyOut);
-}
-
-
-/**********************************************************************
- * VarCyFromBool [OLEAUT32.106]
- * Convert boolean to currency
- */
-HRESULT WINAPI VarCyFromBool(VARIANT_BOOL boolIn, CY* pcyOut) {
- if (boolIn < 0) pcyOut->s.Hi = -1;
- else pcyOut->s.Hi = 0;
- pcyOut->s.Lo = (ULONG)boolIn * (ULONG)10000;
-
- return S_OK;
-}
-
-/**********************************************************************
- * VarCyFromI1 [OLEAUT32.225]
- * Convert signed char to currency
- */
-HRESULT WINAPI VarCyFromI1(signed char cIn, CY* pcyOut) {
- if (cIn < 0) pcyOut->s.Hi = -1;
- else pcyOut->s.Hi = 0;
- pcyOut->s.Lo = (ULONG)cIn * (ULONG)10000;
-
- return S_OK;
-}
-
-/**********************************************************************
- * VarCyFromUI2 [OLEAUT32.226]
- * Convert unsigned short to currency
- */
-HRESULT WINAPI VarCyFromUI2(USHORT usIn, CY* pcyOut) {
- pcyOut->s.Hi = 0;
- pcyOut->s.Lo = (ULONG)usIn * (ULONG)10000;
-
- return S_OK;
-}
-
-/**********************************************************************
- * VarCyFromUI4 [OLEAUT32.227]
- * Convert unsigned long to currency
- */
-HRESULT WINAPI VarCyFromUI4(ULONG ulIn, CY* pcyOut) {
- double t = (double)ulIn * (double)10000;
- pcyOut->s.Hi = (LONG)(t / (double)4294967296.0);
- pcyOut->s.Lo = (ULONG)fmod(t, (double)4294967296.0);
-
- return S_OK;
-}
-
-/**********************************************************************
* DosDateTimeToVariantTime [OLEAUT32.14]
* Convert dos representation of time to the date and time representation
* stored in a variant.
@@ -3666,15 +3533,6 @@
}
/**********************************************************************
- * VarFormatCurrency [OLEAUT32.127]
- */
-HRESULT WINAPI VarFormatCurrency(LPVARIANT var, INT digits, INT lead, INT paren, INT group, ULONG dwFlags, BSTR *out)
-{
- FIXME("%p %d %d %d %d %lx %p\n", var, digits, lead, paren, group, dwFlags, out);
- return E_NOTIMPL;
-}
-
-/**********************************************************************
* VariantTimeToDosDateTime [OLEAUT32.13]
* Convert variant representation of time to the date and time representation
* stored in dos.
@@ -5148,24 +5006,6 @@
}
/**********************************************************************
- * VarCyMulI4 [OLEAUT32.304]
- * Multiply currency value by integer
- */
-HRESULT WINAPI VarCyMulI4(CY cyIn, LONG mulBy, CY *pcyOut) {
-
- double cyVal = 0;
- HRESULT rc = S_OK;
-
- rc = VarR8FromCy(cyIn, &cyVal);
- if (rc == S_OK) {
- rc = VarCyFromR8((cyVal * (double) mulBy), pcyOut);
- TRACE("Multiply %f by %ld = %f [%ld,%lu]\n", cyVal, mulBy, (cyVal * (double) mulBy),
- pcyOut->s.Hi, pcyOut->s.Lo);
- }
- return rc;
-}
-
-/**********************************************************************
* VarMod [OLEAUT32.154]
*
*/