From 90d8741d23c9cc19f7f9d285efea2c7f8467af1a Mon Sep 17 00:00:00 2001 From: Alexandru Balut Date: Sun, 2 Dec 2007 17:17:27 +0100 Subject: [PATCH] oleaut32: Implement VarWeekdayName + tests. --- dlls/oleaut32/oleaut32.spec | 2 +- dlls/oleaut32/tests/varformat.c | 103 ++++++++++++++++++++++++++++++++ dlls/oleaut32/varformat.c | 70 ++++++++++++++++++++++ 3 files changed, 174 insertions(+), 1 deletion(-) diff --git a/dlls/oleaut32/oleaut32.spec b/dlls/oleaut32/oleaut32.spec index abffbd26e52..7b764ef96b6 100644 --- a/dlls/oleaut32/oleaut32.spec +++ b/dlls/oleaut32/oleaut32.spec @@ -124,7 +124,7 @@ 125 stdcall VarBoolFromStr(wstr long long ptr) 126 stdcall VarBoolFromDisp(ptr long ptr) 127 stdcall VarFormatCurrency(ptr long long long long long ptr) -128 stub VarWeekdayName # stdcall (long long long long ptr) +128 stdcall VarWeekdayName(long long long long ptr) 129 stdcall VarMonthName(long long long ptr) 130 stdcall VarUI1FromI2(long ptr) 131 stdcall VarUI1FromI4(long ptr) diff --git a/dlls/oleaut32/tests/varformat.c b/dlls/oleaut32/tests/varformat.c index f7c7c28bd8d..5a13e67fa1f 100644 --- a/dlls/oleaut32/tests/varformat.c +++ b/dlls/oleaut32/tests/varformat.c @@ -42,6 +42,7 @@ static HMODULE hOleaut32; static HRESULT (WINAPI *pVarFormatNumber)(LPVARIANT,int,int,int,int,ULONG,BSTR*); static HRESULT (WINAPI *pVarFormat)(LPVARIANT,LPOLESTR,int,int,ULONG,BSTR*); +static HRESULT (WINAPI *pVarWeekdayName)(int,int,int,ULONG,BSTR*); /* Have I8/UI8 data type? */ #define HAVE_OLEAUT32_I8 HAVE_FUNC(VarI8FromI1) @@ -392,10 +393,112 @@ static void test_VarFormat(void) VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,""); } +static const char *szVarWdnFail = \ + "VarWeekdayName (%d, %d, %d, %d, %x): returned %8x, expected %8x\n"; +#define VARWDN(iWeekday, fAbbrev, iFirstDay, dwFlags, ret, buff, out, freeOut) \ +do { \ + hres = pVarWeekdayName(iWeekday, fAbbrev, iFirstDay, dwFlags, &out); \ + if (SUCCEEDED(hres)) { \ + WideCharToMultiByte(CP_ACP, 0, out, -1, buff, sizeof(buff), 0, 0); \ + if (freeOut) SysFreeString(out); \ + } else { \ + buff[0] = '\0'; \ + } \ + ok(hres == ret, \ + szVarWdnFail, \ + iWeekday, fAbbrev, iFirstDay, dwFlags, &out, hres, ret \ + ); \ +} while(0) + +#define VARWDN_F(iWeekday, fAbbrev, iFirstDay, dwFlags, ret) \ + VARWDN(iWeekday, fAbbrev, iFirstDay, dwFlags, ret, buff, out, 1) + +#define VARWDN_O(iWeekday, fAbbrev, iFirstDay, dwFlags) \ + VARWDN(iWeekday, fAbbrev, iFirstDay, dwFlags, S_OK, buff, out, 0) + +static void test_VarWeekdayName(void) +{ + char buff[256]; + BSTR out = NULL; + HRESULT hres; + int iWeekday, fAbbrev, iFirstDay; + BSTR dayNames[7][2]; /* Monday-Sunday, full/abbr */ + DWORD defaultFirstDay; + int firstDay; + int day; + int size; + DWORD localeValue; + + CHECKPTR(VarWeekdayName); + + /* Initialize days' names */ + for (day = 0; day <= 6; ++day) + { + for (fAbbrev = 0; fAbbrev <= 1; ++fAbbrev) + { + localeValue = fAbbrev ? LOCALE_SABBREVDAYNAME1 : LOCALE_SDAYNAME1; + localeValue += day; + size = GetLocaleInfoW(LOCALE_USER_DEFAULT, localeValue, NULL, 0); + dayNames[day][fAbbrev] = SysAllocStringLen(NULL, size - 1); + GetLocaleInfoW(LOCALE_USER_DEFAULT, localeValue, + dayNames[day][fAbbrev], size); + } + } + + /* Get the user's first day of week. 0=Monday, .. */ + GetLocaleInfoW( + LOCALE_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK | LOCALE_RETURN_NUMBER, + (LPWSTR)&defaultFirstDay, sizeof(defaultFirstDay) / sizeof(WCHAR)); + + /* Check invalid arguments */ + VARWDN_F(0, 0, 4, 0, E_INVALIDARG); + VARWDN_F(8, 0, 4, 0, E_INVALIDARG); + VARWDN_F(4, 0, -1, 0, E_INVALIDARG); + VARWDN_F(4, 0, 8, 0, E_INVALIDARG); + + hres = pVarWeekdayName(1, 0, 0, 0, NULL); + ok(E_INVALIDARG == hres, + "Null pointer: expected E_INVALIDARG, got 0x%08x\n", hres); + + /* Check all combinations */ + for (iWeekday = 1; iWeekday <= 7; ++iWeekday) + { + for (fAbbrev = 0; fAbbrev <= 1; ++fAbbrev) + { + /* 0 = Default, 1 = Sunday, 2 = Monday, .. */ + for (iFirstDay = 0; iFirstDay <= 7; ++iFirstDay) + { + VARWDN_O(iWeekday, fAbbrev, iFirstDay, 0); + if (iFirstDay == 0) + firstDay = defaultFirstDay; + else + /* Translate from 0=Sunday to 0=Monday in the modulo 7 space */ + firstDay = iFirstDay - 2; + day = (7 + iWeekday - 1 + firstDay) % 7; + ok(VARCMP_EQ == VarBstrCmp(out, dayNames[day][fAbbrev], + LOCALE_USER_DEFAULT, 0), + "VarWeekdayName(%d,%d,%d): got wrong dayname: '%s'\n", + iWeekday, fAbbrev, iFirstDay, buff); + SysFreeString(out); + } + } + } + + /* Cleanup */ + for (day = 0; day <= 6; ++day) + { + for (fAbbrev = 0; fAbbrev <= 1; ++fAbbrev) + { + SysFreeString(dayNames[day][fAbbrev]); + } + } +} + START_TEST(varformat) { hOleaut32 = GetModuleHandleA("oleaut32.dll"); test_VarFormatNumber(); test_VarFormat(); + test_VarWeekdayName(); } diff --git a/dlls/oleaut32/varformat.c b/dlls/oleaut32/varformat.c index 5faecd24ece..23b7e57a2e0 100644 --- a/dlls/oleaut32/varformat.c +++ b/dlls/oleaut32/varformat.c @@ -2498,3 +2498,73 @@ HRESULT WINAPI VarMonthName(INT iMonth, INT fAbbrev, ULONG dwFlags, BSTR *pbstrO } return S_OK; } + +/********************************************************************** + * VarWeekdayName [OLEAUT32.129] + * + * Print the specified weekday as localized name. + * + * PARAMS + * iWeekday [I] day of week, 1..7, 1="the first day of the week" + * fAbbrev [I] 0 - full name, !0 - abbreviated name + * iFirstDay [I] first day of week, + * 0=system default, 1=Sunday, 2=Monday, .. (contrary to MSDN) + * dwFlags [I] flag stuff. only VAR_CALENDAR_HIJRI possible. + * pbstrOut [O] Destination for weekday name. + * + * RETURNS + * Success: S_OK, pbstrOut contains the name. + * Failure: E_INVALIDARG, if any parameter is invalid. + * E_OUTOFMEMORY, if enough memory cannot be allocated. + */ +HRESULT WINAPI VarWeekdayName(INT iWeekday, INT fAbbrev, INT iFirstDay, + ULONG dwFlags, BSTR *pbstrOut) +{ + DWORD localeValue; + INT size; + + /* Windows XP oleaut32.dll doesn't allow iWekday==0, contrary to MSDN */ + if (iWeekday < 1 || iWeekday > 7) + return E_INVALIDARG; + if (iFirstDay < 0 || iFirstDay > 7) + return E_INVALIDARG; + if (!pbstrOut) + return E_INVALIDARG; + + if (dwFlags) + FIXME("Does not support dwFlags 0x%x, ignoring.\n", dwFlags); + + /* If we have to use the default firstDay, find which one it is */ + if (iFirstDay == 0) { + DWORD firstDay; + localeValue = LOCALE_RETURN_NUMBER | LOCALE_IFIRSTDAYOFWEEK; + size = GetLocaleInfoW(LOCALE_USER_DEFAULT, localeValue, + (LPWSTR)&firstDay, sizeof(firstDay) / sizeof(WCHAR)); + if (!size) { + ERR("GetLocaleInfo 0x%x failed.\n", localeValue); + return HRESULT_FROM_WIN32(GetLastError()); + } + iFirstDay = firstDay + 2; + } + + /* Determine what we need to return */ + localeValue = fAbbrev ? LOCALE_SABBREVDAYNAME1 : LOCALE_SDAYNAME1; + localeValue += (7 + iWeekday - 1 + iFirstDay - 2) % 7; + + /* Determine the size of the data, allocate memory and retrieve the data */ + size = GetLocaleInfoW(LOCALE_USER_DEFAULT, localeValue, NULL, 0); + if (!size) { + ERR("GetLocaleInfo 0x%x failed.\n", localeValue); + return HRESULT_FROM_WIN32(GetLastError()); + } + *pbstrOut = SysAllocStringLen(NULL, size - 1); + if (!*pbstrOut) + return E_OUTOFMEMORY; + size = GetLocaleInfoW(LOCALE_USER_DEFAULT, localeValue, *pbstrOut, size); + if (!size) { + ERR("GetLocaleInfo 0x%x failed in 2nd stage?!\n", localeValue); + SysFreeString(*pbstrOut); + return HRESULT_FROM_WIN32(GetLastError()); + } + return S_OK; +}