ReactOS 0.4.16-dev-297-gc569aee
varformat.c File Reference
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "variant.h"
#include "wine/debug.h"
Include dependency graph for varformat.c:

Go to the source code of this file.

Classes

struct  tagFMT_SHORT_HEADER
 
struct  tagFMT_HEADER
 
struct  tagFMT_STRING_HEADER
 
struct  tagFMT_NUMBER_HEADER
 
struct  tagFMT_DATE_HEADER
 
struct  tagNAMED_FORMAT
 

Macros

#define LCID_US   MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT)
 
#define FMT_TYPE_UNKNOWN   0x0
 
#define FMT_TYPE_GENERAL   0x1
 
#define FMT_TYPE_NUMBER   0x2
 
#define FMT_TYPE_DATE   0x3
 
#define FMT_TYPE_STRING   0x4
 
#define FMT_TO_STRING   0x0 /* If header->size == this, act like VB's Str() fn */
 
#define FmtGetPositive(x)   (x->starts[0])
 
#define FmtGetNegative(x)   (x->starts[1] ? x->starts[1] : x->starts[0])
 
#define FmtGetZero(x)   (x->starts[2] ? x->starts[2] : x->starts[0])
 
#define FmtGetNull(x)   (x->starts[3] ? x->starts[3] : x->starts[0])
 
#define FMT_FLAG_LT   0x1 /* Has '<' (lower case) */
 
#define FMT_FLAG_GT   0x2 /* Has '>' (upper case) */
 
#define FMT_FLAG_RTL   0x4 /* Has '!' (Copy right to left) */
 
#define FMT_FLAG_PERCENT   0x1 /* Has '%' (Percentage) */
 
#define FMT_FLAG_EXPONENT   0x2 /* Has 'e' (Exponent/Scientific notation) */
 
#define FMT_FLAG_THOUSANDS   0x4 /* Has ',' (Standard use of the thousands separator) */
 
#define FMT_FLAG_BOOL   0x20 /* Boolean format */
 
#define FMT_GEN_COPY   0x00 /* \n, "lit" => 0,pos,len: Copy len chars from input+pos */
 
#define FMT_GEN_INLINE   0x01 /* => 1,len,[chars]: Copy len chars from token stream */
 
#define FMT_GEN_END   0x02 /* \0,; => 2: End of the tokenised format */
 
#define FMT_DATE_TIME_SEP   0x03 /* Time separator char */
 
#define FMT_DATE_DATE_SEP   0x04 /* Date separator char */
 
#define FMT_DATE_GENERAL   0x05 /* General format date */
 
#define FMT_DATE_QUARTER   0x06 /* Quarter of the year from 1-4 */
 
#define FMT_DATE_TIME_SYS   0x07 /* System long time format */
 
#define FMT_DATE_DAY   0x08 /* Day with no leading 0 */
 
#define FMT_DATE_DAY_0   0x09 /* Day with leading 0 */
 
#define FMT_DATE_DAY_SHORT   0x0A /* Short day name */
 
#define FMT_DATE_DAY_LONG   0x0B /* Long day name */
 
#define FMT_DATE_SHORT   0x0C /* Short date format */
 
#define FMT_DATE_LONG   0x0D /* Long date format */
 
#define FMT_DATE_MEDIUM   0x0E /* Medium date format */
 
#define FMT_DATE_DAY_WEEK   0x0F /* First day of the week */
 
#define FMT_DATE_WEEK_YEAR   0x10 /* First week of the year */
 
#define FMT_DATE_MON   0x11 /* Month with no leading 0 */
 
#define FMT_DATE_MON_0   0x12 /* Month with leading 0 */
 
#define FMT_DATE_MON_SHORT   0x13 /* Short month name */
 
#define FMT_DATE_MON_LONG   0x14 /* Long month name */
 
#define FMT_DATE_YEAR_DOY   0x15 /* Day of the year with no leading 0 */
 
#define FMT_DATE_YEAR_0   0x16 /* 2 digit year with leading 0 */
 
#define FMT_DATE_YEAR_LONG   0x18 /* 4 digit year */
 
#define FMT_DATE_MIN   0x1A /* Minutes with no leading 0 */
 
#define FMT_DATE_MIN_0   0x1B /* Minutes with leading 0 */
 
#define FMT_DATE_SEC   0x1C /* Seconds with no leading 0 */
 
#define FMT_DATE_SEC_0   0x1D /* Seconds with leading 0 */
 
#define FMT_DATE_HOUR   0x1E /* Hours with no leading 0 */
 
#define FMT_DATE_HOUR_0   0x1F /* Hours with leading 0 */
 
#define FMT_DATE_HOUR_12   0x20 /* Hours with no leading 0, 12 hour clock */
 
#define FMT_DATE_HOUR_12_0   0x21 /* Hours with leading 0, 12 hour clock */
 
#define FMT_DATE_TIME_UNK2   0x23 /* same as FMT_DATE_HOUR_0, for "short time" format */
 
#define FMT_DATE_AMPM_SYS1   0x2E /* AM/PM as defined by system settings */
 
#define FMT_DATE_AMPM_UPPER   0x2F /* Upper-case AM or PM */
 
#define FMT_DATE_A_UPPER   0x30 /* Upper-case A or P */
 
#define FMT_DATE_AMPM_SYS2   0x31 /* AM/PM as defined by system settings */
 
#define FMT_DATE_AMPM_LOWER   0x32 /* Lower-case AM or PM */
 
#define FMT_DATE_A_LOWER   0x33 /* Lower-case A or P */
 
#define FMT_NUM_COPY_ZERO   0x34 /* Copy 1 digit or 0 if no digit */
 
#define FMT_NUM_COPY_SKIP   0x35 /* Copy 1 digit or skip if no digit */
 
#define FMT_NUM_DECIMAL   0x36 /* Decimal separator */
 
#define FMT_NUM_EXP_POS_U   0x37 /* Scientific notation, uppercase, + sign */
 
#define FMT_NUM_EXP_NEG_U   0x38 /* Scientific notation, uppercase, - sign */
 
#define FMT_NUM_EXP_POS_L   0x39 /* Scientific notation, lowercase, + sign */
 
#define FMT_NUM_EXP_NEG_L   0x3A /* Scientific notation, lowercase, - sign */
 
#define FMT_NUM_CURRENCY   0x3B /* Currency symbol */
 
#define FMT_NUM_TRUE_FALSE   0x3D /* Convert to "True" or "False" */
 
#define FMT_NUM_YES_NO   0x3E /* Convert to "Yes" or "No" */
 
#define FMT_NUM_ON_OFF   0x3F /* Convert to "On" or "Off" */
 
#define FMT_STR_COPY_SPACE   0x40 /* Copy len chars with space if no char */
 
#define FMT_STR_COPY_SKIP   0x41 /* Copy len chars or skip if no char */
 
#define NEED_SPACE(x)   if (cbTok < (int)(x)) return TYPE_E_BUFFERTOOSMALL; cbTok -= (x)
 
#define COULD_BE(typ)   ((!fmt_number && header->type==FMT_TYPE_UNKNOWN)||header->type==typ)
 
#define FMT_STATE_OPEN_COPY   0x1 /* Last token written was a copy */
 
#define FMT_STATE_WROTE_DECIMAL   0x2 /* Already wrote a decimal separator */
 
#define FMT_STATE_SEEN_HOURS   0x4 /* See the hh specifier */
 
#define FMT_STATE_WROTE_MINUTES   0x8 /* Wrote minutes */
 
#define NUM_WROTE_DEC   0x01 /* Written the decimal separator */
 
#define NUM_WRITE_ON   0x02 /* Started to write the number */
 
#define NUM_WROTE_SIGN   0x04 /* Written the negative sign */
 
#define NUMBER_VTBITS
 
#define GETLOCALENUMBER(type, field)
 

Typedefs

typedef struct tagFMT_SHORT_HEADER FMT_SHORT_HEADER
 
typedef struct tagFMT_HEADER FMT_HEADER
 
typedef struct tagFMT_STRING_HEADER FMT_STRING_HEADER
 
typedef struct tagFMT_NUMBER_HEADER FMT_NUMBER_HEADER
 
typedef struct tagFMT_DATE_HEADER FMT_DATE_HEADER
 
typedef struct tagNAMED_FORMAT NAMED_FORMAT
 
typedef const NAMED_FORMATLPCNAMED_FORMAT
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (variant)
 
static int __cdecl FormatCompareFn (const void *l, const void *r)
 
static const BYTEVARIANT_GetNamedFormat (LPCWSTR lpszFormat)
 
HRESULT WINAPI VarTokenizeFormatString (LPOLESTR lpszFormat, LPBYTE rgbTok, int cbTok, int nFirstDay, int nFirstWeek, LCID lcid, int *pcbActual)
 
static HRESULT VARIANT_FormatNumber (LPVARIANT pVarIn, LPOLESTR lpszFormat, LPBYTE rgbTok, ULONG dwFlags, BSTR *pbstrOut, LCID lcid)
 
static HRESULT VARIANT_FormatDate (LPVARIANT pVarIn, LPOLESTR lpszFormat, LPBYTE rgbTok, ULONG dwFlags, BSTR *pbstrOut, LCID lcid)
 
static HRESULT VARIANT_FormatString (LPVARIANT pVarIn, LPOLESTR lpszFormat, LPBYTE rgbTok, ULONG dwFlags, BSTR *pbstrOut, LCID lcid)
 
HRESULT WINAPI VarFormatFromTokens (LPVARIANT pVarIn, LPOLESTR lpszFormat, LPBYTE rgbTok, ULONG dwFlags, BSTR *pbstrOut, LCID lcid)
 
HRESULT WINAPI VarFormat (LPVARIANT pVarIn, LPOLESTR lpszFormat, int nFirstDay, int nFirstWeek, ULONG dwFlags, BSTR *pbstrOut)
 
HRESULT WINAPI VarFormatDateTime (LPVARIANT pVarIn, INT nFormat, ULONG dwFlags, BSTR *pbstrOut)
 
HRESULT WINAPI VarFormatNumber (LPVARIANT pVarIn, INT nDigits, INT nLeading, INT nParens, INT nGrouping, ULONG dwFlags, BSTR *pbstrOut)
 
HRESULT WINAPI VarFormatPercent (LPVARIANT pVarIn, INT nDigits, INT nLeading, INT nParens, INT nGrouping, ULONG dwFlags, BSTR *pbstrOut)
 
HRESULT WINAPI VarFormatCurrency (LPVARIANT pVarIn, INT nDigits, INT nLeading, INT nParens, INT nGrouping, ULONG dwFlags, BSTR *pbstrOut)
 
HRESULT WINAPI VarMonthName (INT iMonth, INT fAbbrev, ULONG dwFlags, BSTR *pbstrOut)
 
HRESULT WINAPI VarWeekdayName (INT iWeekday, INT fAbbrev, INT iFirstDay, ULONG dwFlags, BSTR *pbstrOut)
 

Variables

static const WCHAR szPercent_d [] = { '%','d','\0' }
 
static const WCHAR szPercentZeroTwo_d [] = { '%','0','2','d','\0' }
 
static const WCHAR szPercentZeroStar_d [] = { '%','0','*','d','\0' }
 
static const WCHAR szGeneralDate [] = { 'G','e','n','e','r','a','l',' ','D','a','t','e','\0' }
 
static const BYTE fmtGeneralDate [0x0a]
 
static const WCHAR szShortDate [] = { 'S','h','o','r','t',' ','D','a','t','e','\0' }
 
static const BYTE fmtShortDate [0x0a]
 
static const WCHAR szMediumDate [] = { 'M','e','d','i','u','m',' ','D','a','t','e','\0' }
 
static const BYTE fmtMediumDate [0x0a]
 
static const WCHAR szLongDate [] = { 'L','o','n','g',' ','D','a','t','e','\0' }
 
static const BYTE fmtLongDate [0x0a]
 
static const WCHAR szShortTime [] = { 'S','h','o','r','t',' ','T','i','m','e','\0' }
 
static const BYTE fmtShortTime [0x0c]
 
static const WCHAR szMediumTime [] = { 'M','e','d','i','u','m',' ','T','i','m','e','\0' }
 
static const BYTE fmtMediumTime [0x11]
 
static const WCHAR szLongTime [] = { 'L','o','n','g',' ','T','i','m','e','\0' }
 
static const BYTE fmtLongTime [0x0d]
 
static const WCHAR szTrueFalse [] = { 'T','r','u','e','/','F','a','l','s','e','\0' }
 
static const BYTE fmtTrueFalse [0x0d]
 
static const WCHAR szYesNo [] = { 'Y','e','s','/','N','o','\0' }
 
static const BYTE fmtYesNo [0x0d]
 
static const WCHAR szOnOff [] = { 'O','n','/','O','f','f','\0' }
 
static const BYTE fmtOnOff [0x0d]
 
static const WCHAR szGeneralNumber [] = { 'G','e','n','e','r','a','l',' ','N','u','m','b','e','r','\0' }
 
static const BYTE fmtGeneralNumber [sizeof(FMT_HEADER)]
 
static const WCHAR szCurrency [] = { 'C','u','r','r','e','n','c','y','\0' }
 
static const BYTE fmtCurrency [0x26]
 
static const WCHAR szFixed [] = { 'F','i','x','e','d','\0' }
 
static const BYTE fmtFixed [0x11]
 
static const WCHAR szStandard [] = { 'S','t','a','n','d','a','r','d','\0' }
 
static const BYTE fmtStandard [0x11]
 
static const WCHAR szPercent [] = { 'P','e','r','c','e','n','t','\0' }
 
static const BYTE fmtPercent [0x15]
 
static const WCHAR szScientific [] = { 'S','c','i','e','n','t','i','f','i','c','\0' }
 
static const BYTE fmtScientific [0x13]
 
static const NAMED_FORMAT VARIANT_NamedFormats []
 

Macro Definition Documentation

◆ COULD_BE

#define COULD_BE (   typ)    ((!fmt_number && header->type==FMT_TYPE_UNKNOWN)||header->type==typ)

Definition at line 458 of file varformat.c.

◆ FMT_DATE_A_LOWER

#define FMT_DATE_A_LOWER   0x33 /* Lower-case A or P */

Definition at line 259 of file varformat.c.

◆ FMT_DATE_A_UPPER

#define FMT_DATE_A_UPPER   0x30 /* Upper-case A or P */

Definition at line 256 of file varformat.c.

◆ FMT_DATE_AMPM_LOWER

#define FMT_DATE_AMPM_LOWER   0x32 /* Lower-case AM or PM */

Definition at line 258 of file varformat.c.

◆ FMT_DATE_AMPM_SYS1

#define FMT_DATE_AMPM_SYS1   0x2E /* AM/PM as defined by system settings */

Definition at line 254 of file varformat.c.

◆ FMT_DATE_AMPM_SYS2

#define FMT_DATE_AMPM_SYS2   0x31 /* AM/PM as defined by system settings */

Definition at line 257 of file varformat.c.

◆ FMT_DATE_AMPM_UPPER

#define FMT_DATE_AMPM_UPPER   0x2F /* Upper-case AM or PM */

Definition at line 255 of file varformat.c.

◆ FMT_DATE_DATE_SEP

#define FMT_DATE_DATE_SEP   0x04 /* Date separator char */

Definition at line 223 of file varformat.c.

◆ FMT_DATE_DAY

#define FMT_DATE_DAY   0x08 /* Day with no leading 0 */

Definition at line 227 of file varformat.c.

◆ FMT_DATE_DAY_0

#define FMT_DATE_DAY_0   0x09 /* Day with leading 0 */

Definition at line 228 of file varformat.c.

◆ FMT_DATE_DAY_LONG

#define FMT_DATE_DAY_LONG   0x0B /* Long day name */

Definition at line 230 of file varformat.c.

◆ FMT_DATE_DAY_SHORT

#define FMT_DATE_DAY_SHORT   0x0A /* Short day name */

Definition at line 229 of file varformat.c.

◆ FMT_DATE_DAY_WEEK

#define FMT_DATE_DAY_WEEK   0x0F /* First day of the week */

Definition at line 234 of file varformat.c.

◆ FMT_DATE_GENERAL

#define FMT_DATE_GENERAL   0x05 /* General format date */

Definition at line 224 of file varformat.c.

◆ FMT_DATE_HOUR

#define FMT_DATE_HOUR   0x1E /* Hours with no leading 0 */

Definition at line 248 of file varformat.c.

◆ FMT_DATE_HOUR_0

#define FMT_DATE_HOUR_0   0x1F /* Hours with leading 0 */

Definition at line 249 of file varformat.c.

◆ FMT_DATE_HOUR_12

#define FMT_DATE_HOUR_12   0x20 /* Hours with no leading 0, 12 hour clock */

Definition at line 250 of file varformat.c.

◆ FMT_DATE_HOUR_12_0

#define FMT_DATE_HOUR_12_0   0x21 /* Hours with leading 0, 12 hour clock */

Definition at line 251 of file varformat.c.

◆ FMT_DATE_LONG

#define FMT_DATE_LONG   0x0D /* Long date format */

Definition at line 232 of file varformat.c.

◆ FMT_DATE_MEDIUM

#define FMT_DATE_MEDIUM   0x0E /* Medium date format */

Definition at line 233 of file varformat.c.

◆ FMT_DATE_MIN

#define FMT_DATE_MIN   0x1A /* Minutes with no leading 0 */

Definition at line 244 of file varformat.c.

◆ FMT_DATE_MIN_0

#define FMT_DATE_MIN_0   0x1B /* Minutes with leading 0 */

Definition at line 245 of file varformat.c.

◆ FMT_DATE_MON

#define FMT_DATE_MON   0x11 /* Month with no leading 0 */

Definition at line 236 of file varformat.c.

◆ FMT_DATE_MON_0

#define FMT_DATE_MON_0   0x12 /* Month with leading 0 */

Definition at line 237 of file varformat.c.

◆ FMT_DATE_MON_LONG

#define FMT_DATE_MON_LONG   0x14 /* Long month name */

Definition at line 239 of file varformat.c.

◆ FMT_DATE_MON_SHORT

#define FMT_DATE_MON_SHORT   0x13 /* Short month name */

Definition at line 238 of file varformat.c.

◆ FMT_DATE_QUARTER

#define FMT_DATE_QUARTER   0x06 /* Quarter of the year from 1-4 */

Definition at line 225 of file varformat.c.

◆ FMT_DATE_SEC

#define FMT_DATE_SEC   0x1C /* Seconds with no leading 0 */

Definition at line 246 of file varformat.c.

◆ FMT_DATE_SEC_0

#define FMT_DATE_SEC_0   0x1D /* Seconds with leading 0 */

Definition at line 247 of file varformat.c.

◆ FMT_DATE_SHORT

#define FMT_DATE_SHORT   0x0C /* Short date format */

Definition at line 231 of file varformat.c.

◆ FMT_DATE_TIME_SEP

#define FMT_DATE_TIME_SEP   0x03 /* Time separator char */

Definition at line 222 of file varformat.c.

◆ FMT_DATE_TIME_SYS

#define FMT_DATE_TIME_SYS   0x07 /* System long time format */

Definition at line 226 of file varformat.c.

◆ FMT_DATE_TIME_UNK2

#define FMT_DATE_TIME_UNK2   0x23 /* same as FMT_DATE_HOUR_0, for "short time" format */

Definition at line 252 of file varformat.c.

◆ FMT_DATE_WEEK_YEAR

#define FMT_DATE_WEEK_YEAR   0x10 /* First week of the year */

Definition at line 235 of file varformat.c.

◆ FMT_DATE_YEAR_0

#define FMT_DATE_YEAR_0   0x16 /* 2 digit year with leading 0 */

Definition at line 241 of file varformat.c.

◆ FMT_DATE_YEAR_DOY

#define FMT_DATE_YEAR_DOY   0x15 /* Day of the year with no leading 0 */

Definition at line 240 of file varformat.c.

◆ FMT_DATE_YEAR_LONG

#define FMT_DATE_YEAR_LONG   0x18 /* 4 digit year */

Definition at line 243 of file varformat.c.

◆ FMT_FLAG_BOOL

#define FMT_FLAG_BOOL   0x20 /* Boolean format */

Definition at line 193 of file varformat.c.

◆ FMT_FLAG_EXPONENT

#define FMT_FLAG_EXPONENT   0x2 /* Has 'e' (Exponent/Scientific notation) */

Definition at line 191 of file varformat.c.

◆ FMT_FLAG_GT

#define FMT_FLAG_GT   0x2 /* Has '>' (upper case) */

Definition at line 174 of file varformat.c.

◆ FMT_FLAG_LT

#define FMT_FLAG_LT   0x1 /* Has '<' (lower case) */

Definition at line 173 of file varformat.c.

◆ FMT_FLAG_PERCENT

#define FMT_FLAG_PERCENT   0x1 /* Has '%' (Percentage) */

Definition at line 190 of file varformat.c.

◆ FMT_FLAG_RTL

#define FMT_FLAG_RTL   0x4 /* Has '!' (Copy right to left) */

Definition at line 175 of file varformat.c.

◆ FMT_FLAG_THOUSANDS

#define FMT_FLAG_THOUSANDS   0x4 /* Has ',' (Standard use of the thousands separator) */

Definition at line 192 of file varformat.c.

◆ FMT_GEN_COPY

#define FMT_GEN_COPY   0x00 /* \n, "lit" => 0,pos,len: Copy len chars from input+pos */

Definition at line 219 of file varformat.c.

◆ FMT_GEN_END

#define FMT_GEN_END   0x02 /* \0,; => 2: End of the tokenised format */

Definition at line 221 of file varformat.c.

◆ FMT_GEN_INLINE

#define FMT_GEN_INLINE   0x01 /* => 1,len,[chars]: Copy len chars from token stream */

Definition at line 220 of file varformat.c.

◆ FMT_NUM_COPY_SKIP

#define FMT_NUM_COPY_SKIP   0x35 /* Copy 1 digit or skip if no digit */

Definition at line 261 of file varformat.c.

◆ FMT_NUM_COPY_ZERO

#define FMT_NUM_COPY_ZERO   0x34 /* Copy 1 digit or 0 if no digit */

Definition at line 260 of file varformat.c.

◆ FMT_NUM_CURRENCY

#define FMT_NUM_CURRENCY   0x3B /* Currency symbol */

Definition at line 267 of file varformat.c.

◆ FMT_NUM_DECIMAL

#define FMT_NUM_DECIMAL   0x36 /* Decimal separator */

Definition at line 262 of file varformat.c.

◆ FMT_NUM_EXP_NEG_L

#define FMT_NUM_EXP_NEG_L   0x3A /* Scientific notation, lowercase, - sign */

Definition at line 266 of file varformat.c.

◆ FMT_NUM_EXP_NEG_U

#define FMT_NUM_EXP_NEG_U   0x38 /* Scientific notation, uppercase, - sign */

Definition at line 264 of file varformat.c.

◆ FMT_NUM_EXP_POS_L

#define FMT_NUM_EXP_POS_L   0x39 /* Scientific notation, lowercase, + sign */

Definition at line 265 of file varformat.c.

◆ FMT_NUM_EXP_POS_U

#define FMT_NUM_EXP_POS_U   0x37 /* Scientific notation, uppercase, + sign */

Definition at line 263 of file varformat.c.

◆ FMT_NUM_ON_OFF

#define FMT_NUM_ON_OFF   0x3F /* Convert to "On" or "Off" */

Definition at line 270 of file varformat.c.

◆ FMT_NUM_TRUE_FALSE

#define FMT_NUM_TRUE_FALSE   0x3D /* Convert to "True" or "False" */

Definition at line 268 of file varformat.c.

◆ FMT_NUM_YES_NO

#define FMT_NUM_YES_NO   0x3E /* Convert to "Yes" or "No" */

Definition at line 269 of file varformat.c.

◆ FMT_STATE_OPEN_COPY

#define FMT_STATE_OPEN_COPY   0x1 /* Last token written was a copy */

Definition at line 461 of file varformat.c.

◆ FMT_STATE_SEEN_HOURS

#define FMT_STATE_SEEN_HOURS   0x4 /* See the hh specifier */

Definition at line 463 of file varformat.c.

◆ FMT_STATE_WROTE_DECIMAL

#define FMT_STATE_WROTE_DECIMAL   0x2 /* Already wrote a decimal separator */

Definition at line 462 of file varformat.c.

◆ FMT_STATE_WROTE_MINUTES

#define FMT_STATE_WROTE_MINUTES   0x8 /* Wrote minutes */

Definition at line 464 of file varformat.c.

◆ FMT_STR_COPY_SKIP

#define FMT_STR_COPY_SKIP   0x41 /* Copy len chars or skip if no char */

Definition at line 272 of file varformat.c.

◆ FMT_STR_COPY_SPACE

#define FMT_STR_COPY_SPACE   0x40 /* Copy len chars with space if no char */

Definition at line 271 of file varformat.c.

◆ FMT_TO_STRING

#define FMT_TO_STRING   0x0 /* If header->size == this, act like VB's Str() fn */

Definition at line 148 of file varformat.c.

◆ FMT_TYPE_DATE

#define FMT_TYPE_DATE   0x3

Definition at line 145 of file varformat.c.

◆ FMT_TYPE_GENERAL

#define FMT_TYPE_GENERAL   0x1

Definition at line 143 of file varformat.c.

◆ FMT_TYPE_NUMBER

#define FMT_TYPE_NUMBER   0x2

Definition at line 144 of file varformat.c.

◆ FMT_TYPE_STRING

#define FMT_TYPE_STRING   0x4

Definition at line 146 of file varformat.c.

◆ FMT_TYPE_UNKNOWN

#define FMT_TYPE_UNKNOWN   0x0

Definition at line 142 of file varformat.c.

◆ FmtGetNegative

#define FmtGetNegative (   x)    (x->starts[1] ? x->starts[1] : x->starts[0])

Definition at line 165 of file varformat.c.

◆ FmtGetNull

#define FmtGetNull (   x)    (x->starts[3] ? x->starts[3] : x->starts[0])

Definition at line 167 of file varformat.c.

◆ FmtGetPositive

#define FmtGetPositive (   x)    (x->starts[0])

Definition at line 164 of file varformat.c.

◆ FmtGetZero

#define FmtGetZero (   x)    (x->starts[2] ? x->starts[2] : x->starts[0])

Definition at line 166 of file varformat.c.

◆ GETLOCALENUMBER

#define GETLOCALENUMBER (   type,
  field 
)
Value:
type|LOCALE_RETURN_NUMBER, \
(LPWSTR)&numfmt.field, \
sizeof(numfmt.field)/sizeof(WCHAR))
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: locale.c:1666
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define LOCALE_USER_DEFAULT
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Definition at line 2212 of file varformat.c.

◆ LCID_US

Definition at line 45 of file varformat.c.

◆ NEED_SPACE

#define NEED_SPACE (   x)    if (cbTok < (int)(x)) return TYPE_E_BUFFERTOOSMALL; cbTok -= (x)

Definition at line 455 of file varformat.c.

◆ NUM_WRITE_ON

#define NUM_WRITE_ON   0x02 /* Started to write the number */

Definition at line 1165 of file varformat.c.

◆ NUM_WROTE_DEC

#define NUM_WROTE_DEC   0x01 /* Written the decimal separator */

Definition at line 1164 of file varformat.c.

◆ NUM_WROTE_SIGN

#define NUM_WROTE_SIGN   0x04 /* Written the negative sign */

Definition at line 1166 of file varformat.c.

◆ NUMBER_VTBITS

#define NUMBER_VTBITS
Value:
#define VTBIT_R4
Definition: oleauto.h:760
#define VTBIT_I2
Definition: oleauto.h:754
#define VTBIT_CY
Definition: oleauto.h:762
#define VTBIT_UI1
Definition: oleauto.h:753
#define VTBIT_DECIMAL
Definition: oleauto.h:763
#define VTBIT_UI8
Definition: oleauto.h:759
#define VTBIT_UI4
Definition: oleauto.h:757
#define VTBIT_I8
Definition: oleauto.h:758
#define VTBIT_I4
Definition: oleauto.h:756
#define VTBIT_UI2
Definition: oleauto.h:755
#define VTBIT_I1
Definition: oleauto.h:752
#define VTBIT_R8
Definition: oleauto.h:761
#define VTBIT_INT
Definition: variant.h:45
#define VTBIT_BOOL
Definition: variant.h:39
#define VTBIT_UINT
Definition: variant.h:47

Definition at line 2042 of file varformat.c.

Typedef Documentation

◆ FMT_DATE_HEADER

◆ FMT_HEADER

◆ FMT_NUMBER_HEADER

◆ FMT_SHORT_HEADER

◆ FMT_STRING_HEADER

◆ LPCNAMED_FORMAT

Definition at line 436 of file varformat.c.

◆ NAMED_FORMAT

Function Documentation

◆ FormatCompareFn()

static int __cdecl FormatCompareFn ( const void l,
const void r 
)
static

Definition at line 438 of file varformat.c.

439{
441}
r l[0]
Definition: byte_order.h:168
#define wcsicmp
Definition: compat.h:15
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
Definition: name.c:39

Referenced by VARIANT_GetNamedFormat().

◆ VarFormat()

HRESULT WINAPI VarFormat ( LPVARIANT  pVarIn,
LPOLESTR  lpszFormat,
int  nFirstDay,
int  nFirstWeek,
ULONG  dwFlags,
BSTR pbstrOut 
)

Definition at line 2138 of file varformat.c.

2141{
2142 BYTE buff[256];
2143 HRESULT hres;
2144
2145 TRACE("(%s,%s,%d,%d,0x%08x,%p)\n", debugstr_variant(pVarIn), debugstr_w(lpszFormat),
2146 nFirstDay, nFirstWeek, dwFlags, pbstrOut);
2147
2148 if (!pbstrOut)
2149 return E_INVALIDARG;
2150 *pbstrOut = NULL;
2151
2152 hres = VarTokenizeFormatString(lpszFormat, buff, sizeof(buff), nFirstDay,
2153 nFirstWeek, LOCALE_USER_DEFAULT, NULL);
2154 if (SUCCEEDED(hres))
2155 hres = VarFormatFromTokens(pVarIn, lpszFormat, buff, dwFlags,
2156 pbstrOut, LOCALE_USER_DEFAULT);
2157 TRACE("returning 0x%08x, %s\n", hres, debugstr_w(*pbstrOut));
2158 return hres;
2159}
#define E_INVALIDARG
Definition: ddrawi.h:101
#define NULL
Definition: types.h:112
HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok, int cbTok, int nFirstDay, int nFirstWeek, LCID lcid, int *pcbActual)
Definition: varformat.c:495
HRESULT WINAPI VarFormatFromTokens(LPVARIANT pVarIn, LPOLESTR lpszFormat, LPBYTE rgbTok, ULONG dwFlags, BSTR *pbstrOut, LCID lcid)
Definition: varformat.c:2050
static unsigned char buff[32768]
Definition: fatten.c:17
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define debugstr_w
Definition: kernel32.h:32
static const char * debugstr_variant(const VARIANT *var)
Definition: container.c:46
HRESULT hres
Definition: protocol.c:465
#define TRACE(s)
Definition: solgame.cpp:4
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
unsigned char BYTE
Definition: xxhash.c:193

Referenced by test_VarFormat().

◆ VarFormatCurrency()

HRESULT WINAPI VarFormatCurrency ( LPVARIANT  pVarIn,
INT  nDigits,
INT  nLeading,
INT  nParens,
INT  nGrouping,
ULONG  dwFlags,
BSTR pbstrOut 
)

Definition at line 2420 of file varformat.c.

2423{
2424 HRESULT hRet;
2425 VARIANT vStr;
2426
2427 TRACE("(%s,%d,%d,%d,%d,0x%08x,%p)\n", debugstr_variant(pVarIn), nDigits, nLeading,
2428 nParens, nGrouping, dwFlags, pbstrOut);
2429
2430 if (!pVarIn || !pbstrOut || nDigits > 9)
2431 return E_INVALIDARG;
2432
2433 *pbstrOut = NULL;
2434
2435 V_VT(&vStr) = VT_EMPTY;
2436 hRet = VariantCopyInd(&vStr, pVarIn);
2437
2438 if (SUCCEEDED(hRet))
2439 hRet = VariantChangeTypeEx(&vStr, &vStr, LOCALE_USER_DEFAULT, 0, VT_BSTR);
2440
2441 if (SUCCEEDED(hRet))
2442 {
2443 WCHAR buff[256], decimal[8], thousands[4], currency[13];
2444 CURRENCYFMTW numfmt;
2445
2446 if (nDigits < 0)
2447 GETLOCALENUMBER(LOCALE_IDIGITS, NumDigits);
2448 else
2449 numfmt.NumDigits = nDigits;
2450
2451 if (nLeading == -2)
2452 GETLOCALENUMBER(LOCALE_ILZERO, LeadingZero);
2453 else if (nLeading == -1)
2454 numfmt.LeadingZero = 1;
2455 else
2456 numfmt.LeadingZero = 0;
2457
2458 if (nGrouping == -2)
2459 {
2460 WCHAR grouping[10];
2461 grouping[2] = '\0';
2463 numfmt.Grouping = grouping[2] == '2' ? 32 : grouping[0] - '0';
2464 }
2465 else if (nGrouping == -1)
2466 numfmt.Grouping = 3; /* 3 = "n,nnn.nn" */
2467 else
2468 numfmt.Grouping = 0; /* 0 = No grouping */
2469
2470 if (nParens == -2)
2471 GETLOCALENUMBER(LOCALE_INEGCURR, NegativeOrder);
2472 else if (nParens == -1)
2473 numfmt.NegativeOrder = 0; /* 0 = "(xxx)" */
2474 else
2475 numfmt.NegativeOrder = 1; /* 1 = "-xxx" */
2476
2477 GETLOCALENUMBER(LOCALE_ICURRENCY, PositiveOrder);
2478
2479 numfmt.lpDecimalSep = decimal;
2481 numfmt.lpThousandSep = thousands;
2483 numfmt.lpCurrencySymbol = currency;
2485
2486 /* use NLS as per VarFormatNumber() */
2488 {
2489 *pbstrOut = SysAllocString(buff);
2490 if (!*pbstrOut)
2491 hRet = E_OUTOFMEMORY;
2492 }
2493 else
2494 hRet = DISP_E_TYPEMISMATCH;
2495
2496 SysFreeString(V_BSTR(&vStr));
2497 }
2498 return hRet;
2499}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
@ VT_BSTR
Definition: compat.h:2303
@ VT_EMPTY
Definition: compat.h:2295
#define GETLOCALENUMBER(type, field)
Definition: varformat.c:2212
INT WINAPI GetCurrencyFormatW(LCID lcid, DWORD dwFlags, LPCWSTR lpszValue, const CURRENCYFMTW *lpFormat, LPWSTR lpCurrencyStr, int cchOut)
Definition: lcformat.c:1578
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
UINT LeadingZero
Definition: winnls.h:615
LPWSTR lpDecimalSep
Definition: winnls.h:617
UINT NumDigits
Definition: winnls.h:614
LPWSTR lpCurrencySymbol
Definition: winnls.h:621
UINT Grouping
Definition: winnls.h:616
UINT NegativeOrder
Definition: winnls.h:619
LPWSTR lpThousandSep
Definition: winnls.h:618
HRESULT WINAPI VariantChangeTypeEx(VARIANTARG *pvargDest, VARIANTARG *pvargSrc, LCID lcid, USHORT wFlags, VARTYPE vt)
Definition: variant.c:988
HRESULT WINAPI VariantCopyInd(VARIANT *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:847
#define DISP_E_TYPEMISMATCH
Definition: winerror.h:2514
#define LOCALE_SGROUPING
Definition: winnls.h:46
#define LOCALE_SDECIMAL
Definition: winnls.h:44
#define LOCALE_ICURRENCY
Definition: winnls.h:58
#define LOCALE_IDIGITS
Definition: winnls.h:47
#define LOCALE_STHOUSAND
Definition: winnls.h:45
#define LOCALE_ILZERO
Definition: winnls.h:48
#define LOCALE_SCURRENCY
Definition: winnls.h:51
#define LOCALE_INEGCURR
Definition: winnls.h:59

◆ VarFormatDateTime()

HRESULT WINAPI VarFormatDateTime ( LPVARIANT  pVarIn,
INT  nFormat,
ULONG  dwFlags,
BSTR pbstrOut 
)

Definition at line 2190 of file varformat.c.

2191{
2192 static WCHAR szEmpty[] = { '\0' };
2193 const BYTE* lpFmt = NULL;
2194
2195 TRACE("%s,%d,0x%08x,%p)\n", debugstr_variant(pVarIn), nFormat, dwFlags, pbstrOut);
2196
2197 if (!pVarIn || !pbstrOut || nFormat < 0 || nFormat > 4)
2198 return E_INVALIDARG;
2199
2200 switch (nFormat)
2201 {
2202 case 0: lpFmt = fmtGeneralDate; break;
2203 case 1: lpFmt = fmtLongDate; break;
2204 case 2: lpFmt = fmtShortDate; break;
2205 case 3: lpFmt = fmtLongTime; break;
2206 case 4: lpFmt = fmtShortTime; break;
2207 }
2208 return VarFormatFromTokens(pVarIn, szEmpty, (BYTE*)lpFmt, dwFlags,
2209 pbstrOut, LOCALE_USER_DEFAULT);
2210}
static const WCHAR szEmpty[]
Definition: provider.c:50
static const BYTE fmtLongDate[0x0a]
Definition: varformat.c:300
static const BYTE fmtGeneralDate[0x0a]
Definition: varformat.c:276
static const BYTE fmtShortTime[0x0c]
Definition: varformat.c:308
static const BYTE fmtShortDate[0x0a]
Definition: varformat.c:284
static const BYTE fmtLongTime[0x0d]
Definition: varformat.c:325

◆ VarFormatFromTokens()

HRESULT WINAPI VarFormatFromTokens ( LPVARIANT  pVarIn,
LPOLESTR  lpszFormat,
LPBYTE  rgbTok,
ULONG  dwFlags,
BSTR pbstrOut,
LCID  lcid 
)

Definition at line 2050 of file varformat.c.

2053{
2055 VARIANT vTmp;
2056 HRESULT hres;
2057
2058 TRACE("(%p,%s,%p,%x,%p,0x%08x)\n", pVarIn, debugstr_w(lpszFormat),
2059 rgbTok, dwFlags, pbstrOut, lcid);
2060
2061 if (!pbstrOut)
2062 return E_INVALIDARG;
2063
2064 *pbstrOut = NULL;
2065
2066 if (!pVarIn || !rgbTok)
2067 return E_INVALIDARG;
2068
2069 if (V_VT(pVarIn) == VT_NULL)
2070 return S_OK;
2071
2072 if (*rgbTok == FMT_TO_STRING || header->type == FMT_TYPE_GENERAL)
2073 {
2074 /* According to MSDN, general format acts somewhat like the 'Str'
2075 * function in Visual Basic.
2076 */
2077VarFormatFromTokens_AsStr:
2078 V_VT(&vTmp) = VT_EMPTY;
2079 hres = VariantChangeTypeEx(&vTmp, pVarIn, lcid, dwFlags, VT_BSTR);
2080 *pbstrOut = V_BSTR(&vTmp);
2081 }
2082 else
2083 {
2084 if (header->type == FMT_TYPE_NUMBER ||
2085 (header->type == FMT_TYPE_UNKNOWN && ((1 << V_TYPE(pVarIn)) & NUMBER_VTBITS)))
2086 {
2087 hres = VARIANT_FormatNumber(pVarIn, lpszFormat, rgbTok, dwFlags, pbstrOut, lcid);
2088 }
2089 else if (header->type == FMT_TYPE_DATE ||
2090 (header->type == FMT_TYPE_UNKNOWN && V_TYPE(pVarIn) == VT_DATE))
2091 {
2092 hres = VARIANT_FormatDate(pVarIn, lpszFormat, rgbTok, dwFlags, pbstrOut, lcid);
2093 }
2094 else if (header->type == FMT_TYPE_STRING || V_TYPE(pVarIn) == VT_BSTR)
2095 {
2096 hres = VARIANT_FormatString(pVarIn, lpszFormat, rgbTok, dwFlags, pbstrOut, lcid);
2097 }
2098 else
2099 {
2100 ERR("unrecognised format type 0x%02x\n", header->type);
2101 return E_INVALIDARG;
2102 }
2103 /* If the coercion failed, still try to create output, unless the
2104 * VAR_FORMAT_NOSUBSTITUTE flag is set.
2105 */
2108 goto VarFormatFromTokens_AsStr;
2109 }
2110
2111 return hres;
2112}
#define ERR(fmt,...)
Definition: precomp.h:57
@ VT_NULL
Definition: compat.h:2296
@ VT_DATE
Definition: compat.h:2302
static HRESULT VARIANT_FormatDate(LPVARIANT pVarIn, LPOLESTR lpszFormat, LPBYTE rgbTok, ULONG dwFlags, BSTR *pbstrOut, LCID lcid)
Definition: varformat.c:1581
#define FMT_TYPE_STRING
Definition: varformat.c:146
#define FMT_TYPE_NUMBER
Definition: varformat.c:144
#define FMT_TYPE_UNKNOWN
Definition: varformat.c:142
static HRESULT VARIANT_FormatString(LPVARIANT pVarIn, LPOLESTR lpszFormat, LPBYTE rgbTok, ULONG dwFlags, BSTR *pbstrOut, LCID lcid)
Definition: varformat.c:1917
#define FMT_TYPE_GENERAL
Definition: varformat.c:143
#define FMT_TYPE_DATE
Definition: varformat.c:145
static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat, LPBYTE rgbTok, ULONG dwFlags, BSTR *pbstrOut, LCID lcid)
Definition: varformat.c:1169
#define NUMBER_VTBITS
Definition: varformat.c:2042
#define FMT_TO_STRING
Definition: varformat.c:148
#define S_OK
Definition: intsafe.h:52
#define VAR_FORMAT_NOSUBSTITUTE
Definition: oleauto.h:331
#define V_TYPE(v)
Definition: variant.h:30
#define DISP_E_OVERFLOW
Definition: winerror.h:2519

Referenced by test_VarFormatFromTokens(), VarFormat(), and VarFormatDateTime().

◆ VarFormatNumber()

HRESULT WINAPI VarFormatNumber ( LPVARIANT  pVarIn,
INT  nDigits,
INT  nLeading,
INT  nParens,
INT  nGrouping,
ULONG  dwFlags,
BSTR pbstrOut 
)

Definition at line 2241 of file varformat.c.

2243{
2244 HRESULT hRet;
2245 VARIANT vStr;
2246
2247 TRACE("(%s,%d,%d,%d,%d,0x%08x,%p)\n", debugstr_variant(pVarIn), nDigits, nLeading,
2248 nParens, nGrouping, dwFlags, pbstrOut);
2249
2250 if (!pVarIn || !pbstrOut || nDigits > 9)
2251 return E_INVALIDARG;
2252
2253 *pbstrOut = NULL;
2254
2255 V_VT(&vStr) = VT_EMPTY;
2256 hRet = VariantCopyInd(&vStr, pVarIn);
2257
2258 if (SUCCEEDED(hRet))
2259 hRet = VariantChangeTypeEx(&vStr, &vStr, LCID_US, 0, VT_BSTR);
2260
2261 if (SUCCEEDED(hRet))
2262 {
2263 WCHAR buff[256], decimal[8], thousands[8];
2264 NUMBERFMTW numfmt;
2265
2266 /* Although MSDN makes it clear that the native versions of these functions
2267 * are implemented using VarTokenizeFormatString()/VarFormatFromTokens(),
2268 * using NLS gives us the same result.
2269 */
2270 if (nDigits < 0)
2271 GETLOCALENUMBER(LOCALE_IDIGITS, NumDigits);
2272 else
2273 numfmt.NumDigits = nDigits;
2274
2275 if (nLeading == -2)
2276 GETLOCALENUMBER(LOCALE_ILZERO, LeadingZero);
2277 else if (nLeading == -1)
2278 numfmt.LeadingZero = 1;
2279 else
2280 numfmt.LeadingZero = 0;
2281
2282 if (nGrouping == -2)
2283 {
2284 WCHAR grouping[10];
2285 grouping[2] = '\0';
2287 numfmt.Grouping = grouping[2] == '2' ? 32 : grouping[0] - '0';
2288 }
2289 else if (nGrouping == -1)
2290 numfmt.Grouping = 3; /* 3 = "n,nnn.nn" */
2291 else
2292 numfmt.Grouping = 0; /* 0 = No grouping */
2293
2294 if (nParens == -2)
2295 GETLOCALENUMBER(LOCALE_INEGNUMBER, NegativeOrder);
2296 else if (nParens == -1)
2297 numfmt.NegativeOrder = 0; /* 0 = "(xxx)" */
2298 else
2299 numfmt.NegativeOrder = 1; /* 1 = "-xxx" */
2300
2301 numfmt.lpDecimalSep = decimal;
2303 numfmt.lpThousandSep = thousands;
2305
2306 if (GetNumberFormatW(LOCALE_USER_DEFAULT, 0, V_BSTR(&vStr), &numfmt, buff, ARRAY_SIZE(buff)))
2307 {
2308 *pbstrOut = SysAllocString(buff);
2309 if (!*pbstrOut)
2310 hRet = E_OUTOFMEMORY;
2311 }
2312 else
2313 hRet = DISP_E_TYPEMISMATCH;
2314
2315 SysFreeString(V_BSTR(&vStr));
2316 }
2317 return hRet;
2318}
#define LCID_US
Definition: varformat.c:45
INT WINAPI GetNumberFormatW(LCID lcid, DWORD dwFlags, LPCWSTR lpszValue, const NUMBERFMTW *lpFormat, LPWSTR lpNumberStr, int cchOut)
Definition: lcformat.c:1212
UINT NumDigits
Definition: winnls.h:644
LPWSTR lpDecimalSep
Definition: winnls.h:647
UINT Grouping
Definition: winnls.h:646
UINT NegativeOrder
Definition: winnls.h:649
LPWSTR lpThousandSep
Definition: winnls.h:648
UINT LeadingZero
Definition: winnls.h:645
#define LOCALE_INEGNUMBER
Definition: winnls.h:49

Referenced by test_VarFormatNumber(), and VarFormatPercent().

◆ VarFormatPercent()

HRESULT WINAPI VarFormatPercent ( LPVARIANT  pVarIn,
INT  nDigits,
INT  nLeading,
INT  nParens,
INT  nGrouping,
ULONG  dwFlags,
BSTR pbstrOut 
)

Definition at line 2345 of file varformat.c.

2347{
2348 static const WCHAR szPercent[] = { '%','\0' };
2349 static const WCHAR szPercentBracket[] = { '%',')','\0' };
2350 WCHAR buff[256];
2351 HRESULT hRet;
2352 VARIANT vDbl;
2353
2354 TRACE("(%s,%d,%d,%d,%d,0x%08x,%p)\n", debugstr_variant(pVarIn), nDigits, nLeading,
2355 nParens, nGrouping, dwFlags, pbstrOut);
2356
2357 if (!pVarIn || !pbstrOut || nDigits > 9)
2358 return E_INVALIDARG;
2359
2360 *pbstrOut = NULL;
2361
2362 V_VT(&vDbl) = VT_EMPTY;
2363 hRet = VariantCopyInd(&vDbl, pVarIn);
2364
2365 if (SUCCEEDED(hRet))
2366 {
2367 hRet = VariantChangeTypeEx(&vDbl, &vDbl, LOCALE_USER_DEFAULT, 0, VT_R8);
2368
2369 if (SUCCEEDED(hRet))
2370 {
2371 if (V_R8(&vDbl) > (R8_MAX / 100.0))
2372 return DISP_E_OVERFLOW;
2373
2374 V_R8(&vDbl) *= 100.0;
2375 hRet = VarFormatNumber(&vDbl, nDigits, nLeading, nParens,
2376 nGrouping, dwFlags, pbstrOut);
2377
2378 if (SUCCEEDED(hRet))
2379 {
2380 DWORD dwLen = lstrlenW(*pbstrOut);
2381 BOOL bBracket = (*pbstrOut)[dwLen] == ')';
2382
2383 dwLen -= bBracket;
2384 memcpy(buff, *pbstrOut, dwLen * sizeof(WCHAR));
2385 lstrcpyW(buff + dwLen, bBracket ? szPercentBracket : szPercent);
2386 SysFreeString(*pbstrOut);
2387 *pbstrOut = SysAllocString(buff);
2388 if (!*pbstrOut)
2389 hRet = E_OUTOFMEMORY;
2390 }
2391 }
2392 }
2393 return hRet;
2394}
#define lstrcpyW
Definition: compat.h:749
@ VT_R8
Definition: compat.h:2300
#define lstrlenW
Definition: compat.h:750
static const WCHAR szPercent[]
Definition: varformat.c:393
HRESULT WINAPI VarFormatNumber(LPVARIANT pVarIn, INT nDigits, INT nLeading, INT nParens, INT nGrouping, ULONG dwFlags, BSTR *pbstrOut)
Definition: varformat.c:2241
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define V_R8(A)
Definition: oleauto.h:262
#define R8_MAX
Definition: variant.h:73

◆ VARIANT_FormatDate()

static HRESULT VARIANT_FormatDate ( LPVARIANT  pVarIn,
LPOLESTR  lpszFormat,
LPBYTE  rgbTok,
ULONG  dwFlags,
BSTR pbstrOut,
LCID  lcid 
)
static

Definition at line 1581 of file varformat.c.

1584{
1585 WCHAR buff[256], *pBuff = buff;
1586 VARIANT vDate;
1587 UDATE udate;
1588 FMT_HEADER *header = (FMT_HEADER*)rgbTok;
1589 FMT_DATE_HEADER *dateHeader;
1590 const BYTE* pToken = NULL;
1591 HRESULT hRes;
1592
1593 TRACE("(%s,%s,%p,0x%08x,%p,0x%08x)\n", debugstr_variant(pVarIn),
1594 debugstr_w(lpszFormat), rgbTok, dwFlags, pbstrOut, lcid);
1595
1596 V_VT(&vDate) = VT_EMPTY;
1597
1598 if (V_TYPE(pVarIn) == VT_EMPTY || V_TYPE(pVarIn) == VT_NULL)
1599 {
1600 dateHeader = (FMT_DATE_HEADER*)(rgbTok + FmtGetNegative(header));
1601 V_DATE(&vDate) = 0;
1602 }
1603 else
1604 {
1606
1607 hRes = VariantChangeTypeEx(&vDate, pVarIn, lcid, usFlags, VT_DATE);
1608 if (FAILED(hRes))
1609 return hRes;
1610 dateHeader = (FMT_DATE_HEADER*)(rgbTok + FmtGetPositive(header));
1611 }
1612
1613 hRes = VarUdateFromDate(V_DATE(&vDate), 0 /* FIXME: flags? */, &udate);
1614 if (FAILED(hRes))
1615 return hRes;
1616 pToken = (const BYTE*)dateHeader + sizeof(FMT_DATE_HEADER);
1617
1618 while (*pToken != FMT_GEN_END)
1619 {
1620 DWORD dwVal = 0, localeValue = 0, dwFmt = 0;
1621 LPCWSTR szPrintFmt = NULL;
1622 WCHAR defaultChar = '?';
1623
1624 if (pToken - rgbTok > header->size)
1625 {
1626 ERR("Ran off the end of the format!\n");
1627 hRes = E_INVALIDARG;
1628 goto VARIANT_FormatDate_Exit;
1629 }
1630
1631 switch (*pToken)
1632 {
1633 case FMT_GEN_COPY:
1634 TRACE("copy %s\n", debugstr_wn(lpszFormat + pToken[1], pToken[2]));
1635 memcpy(pBuff, lpszFormat + pToken[1], pToken[2] * sizeof(WCHAR));
1636 pBuff += pToken[2];
1637 pToken += 2;
1638 break;
1639
1640 case FMT_GEN_INLINE:
1641 pToken += 2;
1642 TRACE("copy %s\n", debugstr_a((LPCSTR)pToken));
1643 while (*pToken)
1644 *pBuff++ = *pToken++;
1645 break;
1646
1647 case FMT_DATE_TIME_SEP:
1648 TRACE("time separator\n");
1649 localeValue = LOCALE_STIME;
1650 defaultChar = ':';
1651 break;
1652
1653 case FMT_DATE_DATE_SEP:
1654 TRACE("date separator\n");
1655 localeValue = LOCALE_SDATE;
1656 defaultChar = '/';
1657 break;
1658
1659 case FMT_DATE_GENERAL:
1660 {
1661 BSTR date = NULL;
1662 WCHAR *pDate;
1663 hRes = VarBstrFromDate(V_DATE(&vDate), lcid, 0, &date);
1664 if (FAILED(hRes))
1665 goto VARIANT_FormatDate_Exit;
1666 pDate = date;
1667 while (*pDate)
1668 *pBuff++ = *pDate++;
1670 }
1671 break;
1672
1673 case FMT_DATE_QUARTER:
1674 if (udate.st.wMonth <= 3)
1675 *pBuff++ = '1';
1676 else if (udate.st.wMonth <= 6)
1677 *pBuff++ = '2';
1678 else if (udate.st.wMonth <= 9)
1679 *pBuff++ = '3';
1680 else
1681 *pBuff++ = '4';
1682 break;
1683
1684 case FMT_DATE_TIME_SYS:
1685 {
1686 /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
1687 BSTR date = NULL;
1688 WCHAR *pDate;
1689 hRes = VarBstrFromDate(V_DATE(&vDate), lcid, VAR_TIMEVALUEONLY, &date);
1690 if (FAILED(hRes))
1691 goto VARIANT_FormatDate_Exit;
1692 pDate = date;
1693 while (*pDate)
1694 *pBuff++ = *pDate++;
1696 }
1697 break;
1698
1699 case FMT_DATE_DAY:
1700 szPrintFmt = szPercent_d;
1701 dwVal = udate.st.wDay;
1702 break;
1703
1704 case FMT_DATE_DAY_0:
1705 szPrintFmt = szPercentZeroTwo_d;
1706 dwVal = udate.st.wDay;
1707 break;
1708
1709 case FMT_DATE_DAY_SHORT:
1710 /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
1711 TRACE("short day\n");
1712 localeValue = LOCALE_SABBREVDAYNAME1 + (udate.st.wDayOfWeek + 6)%7;
1713 defaultChar = '?';
1714 break;
1715
1716 case FMT_DATE_DAY_LONG:
1717 /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
1718 TRACE("long day\n");
1719 localeValue = LOCALE_SDAYNAME1 + (udate.st.wDayOfWeek + 6)%7;
1720 defaultChar = '?';
1721 break;
1722
1723 case FMT_DATE_SHORT:
1724 /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
1725 dwFmt = LOCALE_SSHORTDATE;
1726 break;
1727
1728 case FMT_DATE_LONG:
1729 /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
1730 dwFmt = LOCALE_SLONGDATE;
1731 break;
1732
1733 case FMT_DATE_MEDIUM:
1734 FIXME("Medium date treated as long date\n");
1735 dwFmt = LOCALE_SLONGDATE;
1736 break;
1737
1738 case FMT_DATE_DAY_WEEK:
1739 szPrintFmt = szPercent_d;
1740 if (pToken[1])
1741 dwVal = udate.st.wDayOfWeek + 2 - pToken[1];
1742 else
1743 {
1744 GetLocaleInfoW(lcid,LOCALE_RETURN_NUMBER|LOCALE_IFIRSTDAYOFWEEK,
1745 (LPWSTR)&dwVal, sizeof(dwVal)/sizeof(WCHAR));
1746 dwVal = udate.st.wDayOfWeek + 1 - dwVal;
1747 }
1748 pToken++;
1749 break;
1750
1751 case FMT_DATE_WEEK_YEAR:
1752 szPrintFmt = szPercent_d;
1753 dwVal = udate.wDayOfYear / 7 + 1;
1754 pToken += 2;
1755 FIXME("Ignoring nFirstDay of %d, nFirstWeek of %d\n", pToken[0], pToken[1]);
1756 break;
1757
1758 case FMT_DATE_MON:
1759 szPrintFmt = szPercent_d;
1760 dwVal = udate.st.wMonth;
1761 break;
1762
1763 case FMT_DATE_MON_0:
1764 szPrintFmt = szPercentZeroTwo_d;
1765 dwVal = udate.st.wMonth;
1766 break;
1767
1768 case FMT_DATE_MON_SHORT:
1769 /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
1770 TRACE("short month\n");
1771 localeValue = LOCALE_SABBREVMONTHNAME1 + udate.st.wMonth - 1;
1772 defaultChar = '?';
1773 break;
1774
1775 case FMT_DATE_MON_LONG:
1776 /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
1777 TRACE("long month\n");
1778 localeValue = LOCALE_SMONTHNAME1 + udate.st.wMonth - 1;
1779 defaultChar = '?';
1780 break;
1781
1782 case FMT_DATE_YEAR_DOY:
1783 szPrintFmt = szPercent_d;
1784 dwVal = udate.wDayOfYear;
1785 break;
1786
1787 case FMT_DATE_YEAR_0:
1788 szPrintFmt = szPercentZeroTwo_d;
1789 dwVal = udate.st.wYear % 100;
1790 break;
1791
1792 case FMT_DATE_YEAR_LONG:
1793 szPrintFmt = szPercent_d;
1794 dwVal = udate.st.wYear;
1795 break;
1796
1797 case FMT_DATE_MIN:
1798 szPrintFmt = szPercent_d;
1799 dwVal = udate.st.wMinute;
1800 break;
1801
1802 case FMT_DATE_MIN_0:
1803 szPrintFmt = szPercentZeroTwo_d;
1804 dwVal = udate.st.wMinute;
1805 break;
1806
1807 case FMT_DATE_SEC:
1808 szPrintFmt = szPercent_d;
1809 dwVal = udate.st.wSecond;
1810 break;
1811
1812 case FMT_DATE_SEC_0:
1813 szPrintFmt = szPercentZeroTwo_d;
1814 dwVal = udate.st.wSecond;
1815 break;
1816
1817 case FMT_DATE_HOUR:
1818 szPrintFmt = szPercent_d;
1819 dwVal = udate.st.wHour;
1820 break;
1821
1822 case FMT_DATE_HOUR_0:
1823 case FMT_DATE_TIME_UNK2:
1824 szPrintFmt = szPercentZeroTwo_d;
1825 dwVal = udate.st.wHour;
1826 break;
1827
1828 case FMT_DATE_HOUR_12:
1829 szPrintFmt = szPercent_d;
1830 dwVal = udate.st.wHour ? udate.st.wHour > 12 ? udate.st.wHour - 12 : udate.st.wHour : 12;
1831 break;
1832
1833 case FMT_DATE_HOUR_12_0:
1834 szPrintFmt = szPercentZeroTwo_d;
1835 dwVal = udate.st.wHour ? udate.st.wHour > 12 ? udate.st.wHour - 12 : udate.st.wHour : 12;
1836 break;
1837
1838 case FMT_DATE_AMPM_SYS1:
1839 case FMT_DATE_AMPM_SYS2:
1840 localeValue = udate.st.wHour < 12 ? LOCALE_S1159 : LOCALE_S2359;
1841 defaultChar = '?';
1842 break;
1843
1845 *pBuff++ = udate.st.wHour < 12 ? 'A' : 'P';
1846 *pBuff++ = 'M';
1847 break;
1848
1849 case FMT_DATE_A_UPPER:
1850 *pBuff++ = udate.st.wHour < 12 ? 'A' : 'P';
1851 break;
1852
1854 *pBuff++ = udate.st.wHour < 12 ? 'a' : 'p';
1855 *pBuff++ = 'm';
1856 break;
1857
1858 case FMT_DATE_A_LOWER:
1859 *pBuff++ = udate.st.wHour < 12 ? 'a' : 'p';
1860 break;
1861
1862 default:
1863 ERR("Unknown token 0x%02x!\n", *pToken);
1864 hRes = E_INVALIDARG;
1865 goto VARIANT_FormatDate_Exit;
1866 }
1867 if (localeValue)
1868 {
1869 *pBuff = '\0';
1870 if (GetLocaleInfoW(lcid, localeValue, pBuff, ARRAY_SIZE(buff)-(pBuff-buff)))
1871 {
1872 TRACE("added %s\n", debugstr_w(pBuff));
1873 while (*pBuff)
1874 pBuff++;
1875 }
1876 else
1877 {
1878 TRACE("added %d %c\n", defaultChar, defaultChar);
1879 *pBuff++ = defaultChar;
1880 }
1881 }
1882 else if (dwFmt)
1883 {
1884 WCHAR fmt_buff[80];
1885
1886 if (!GetLocaleInfoW(lcid, dwFmt, fmt_buff, ARRAY_SIZE(fmt_buff)) ||
1887 !get_date_format(lcid, 0, &udate.st, fmt_buff, pBuff, ARRAY_SIZE(buff)-(pBuff-buff)))
1888 {
1889 hRes = E_INVALIDARG;
1890 goto VARIANT_FormatDate_Exit;
1891 }
1892 while (*pBuff)
1893 pBuff++;
1894 }
1895 else if (szPrintFmt)
1896 {
1897 swprintf(pBuff, szPrintFmt, dwVal);
1898 while (*pBuff)
1899 pBuff++;
1900 }
1901 pToken++;
1902 }
1903
1904VARIANT_FormatDate_Exit:
1905 *pBuff = '\0';
1906 TRACE("buff is %s\n", debugstr_w(buff));
1907 if (SUCCEEDED(hRes))
1908 {
1909 *pbstrOut = SysAllocString(buff);
1910 if (!*pbstrOut)
1911 hRes = E_OUTOFMEMORY;
1912 }
1913 return hRes;
1914}
#define FIXME(fmt,...)
Definition: precomp.h:53
OLECHAR * BSTR
Definition: compat.h:2293
#define FMT_DATE_DAY
Definition: varformat.c:227
#define FmtGetPositive(x)
Definition: varformat.c:164
#define FMT_DATE_HOUR
Definition: varformat.c:248
#define FMT_DATE_MON_SHORT
Definition: varformat.c:238
#define FMT_DATE_SHORT
Definition: varformat.c:231
#define FMT_DATE_A_LOWER
Definition: varformat.c:259
#define FMT_DATE_MON_0
Definition: varformat.c:237
#define FMT_DATE_AMPM_UPPER
Definition: varformat.c:255
#define FMT_DATE_YEAR_LONG
Definition: varformat.c:243
#define FMT_DATE_HOUR_12
Definition: varformat.c:250
#define FMT_DATE_SEC
Definition: varformat.c:246
#define FMT_DATE_HOUR_12_0
Definition: varformat.c:251
#define FMT_DATE_MON_LONG
Definition: varformat.c:239
#define FMT_DATE_DAY_0
Definition: varformat.c:228
#define FmtGetNegative(x)
Definition: varformat.c:165
#define FMT_DATE_DAY_SHORT
Definition: varformat.c:229
#define FMT_DATE_TIME_SYS
Definition: varformat.c:226
#define FMT_DATE_TIME_SEP
Definition: varformat.c:222
#define FMT_DATE_MEDIUM
Definition: varformat.c:233
#define FMT_GEN_COPY
Definition: varformat.c:219
#define FMT_GEN_END
Definition: varformat.c:221
#define FMT_DATE_YEAR_DOY
Definition: varformat.c:240
static const WCHAR szPercent_d[]
Definition: varformat.c:47
#define FMT_DATE_MON
Definition: varformat.c:236
#define FMT_DATE_TIME_UNK2
Definition: varformat.c:252
#define FMT_DATE_WEEK_YEAR
Definition: varformat.c:235
#define FMT_DATE_QUARTER
Definition: varformat.c:225
#define FMT_DATE_MIN_0
Definition: varformat.c:245
#define FMT_DATE_HOUR_0
Definition: varformat.c:249
#define FMT_DATE_DAY_WEEK
Definition: varformat.c:234
#define FMT_DATE_AMPM_LOWER
Definition: varformat.c:258
static const WCHAR szPercentZeroTwo_d[]
Definition: varformat.c:48
#define FMT_DATE_DAY_LONG
Definition: varformat.c:230
#define FMT_DATE_LONG
Definition: varformat.c:232
#define FMT_DATE_GENERAL
Definition: varformat.c:224
#define FMT_DATE_A_UPPER
Definition: varformat.c:256
#define FMT_DATE_DATE_SEP
Definition: varformat.c:223
#define FMT_DATE_AMPM_SYS1
Definition: varformat.c:254
#define FMT_DATE_AMPM_SYS2
Definition: varformat.c:257
#define FMT_DATE_YEAR_0
Definition: varformat.c:241
#define FMT_DATE_SEC_0
Definition: varformat.c:247
#define FMT_GEN_INLINE
Definition: varformat.c:220
#define FMT_DATE_MIN
Definition: varformat.c:244
HRESULT WINAPI VarBstrFromDate(DATE dateIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:6778
#define swprintf
Definition: precomp.h:40
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_wn
Definition: kernel32.h:33
__u16 date
Definition: mkdosfs.c:8
#define VARIANT_CALENDAR_HIJRI
Definition: oleauto.h:313
#define VAR_CALENDAR_HIJRI
Definition: oleauto.h:329
#define VAR_TIMEVALUEONLY
Definition: oleauto.h:326
#define V_DATE(A)
Definition: oleauto.h:231
unsigned short USHORT
Definition: pedump.c:61
Definition: oleauto.h:720
SYSTEMTIME st
Definition: oleauto.h:721
USHORT wDayOfYear
Definition: oleauto.h:722
WORD wYear
Definition: winbase.h:930
WORD wMonth
Definition: winbase.h:931
WORD wHour
Definition: winbase.h:934
WORD wSecond
Definition: winbase.h:936
WORD wMinute
Definition: winbase.h:935
WORD wDay
Definition: winbase.h:933
WORD wDayOfWeek
Definition: winbase.h:932
HRESULT WINAPI VarUdateFromDate(DATE dateIn, ULONG dwFlags, UDATE *lpUdate)
Definition: variant.c:1427
BOOL get_date_format(LCID, DWORD, const SYSTEMTIME *, const WCHAR *, WCHAR *, int) DECLSPEC_HIDDEN
Definition: vartype.c:6668
#define LOCALE_SDATE
Definition: winnls.h:60
#define LOCALE_SDAYNAME1
Definition: winnls.h:79
#define LOCALE_SLONGDATE
Definition: winnls.h:63
#define LOCALE_S1159
Definition: winnls.h:73
#define LOCALE_SSHORTDATE
Definition: winnls.h:62
#define LOCALE_SMONTHNAME1
Definition: winnls.h:93
#define LOCALE_SABBREVMONTHNAME1
Definition: winnls.h:106
#define LOCALE_SABBREVDAYNAME1
Definition: winnls.h:86
#define LOCALE_IFIRSTDAYOFWEEK
Definition: winnls.h:77
#define LOCALE_STIME
Definition: winnls.h:61
#define LOCALE_S2359
Definition: winnls.h:74
const char * LPCSTR
Definition: xmlstorage.h:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by VarFormatFromTokens().

◆ VARIANT_FormatNumber()

static HRESULT VARIANT_FormatNumber ( LPVARIANT  pVarIn,
LPOLESTR  lpszFormat,
LPBYTE  rgbTok,
ULONG  dwFlags,
BSTR pbstrOut,
LCID  lcid 
)
static

Definition at line 1169 of file varformat.c.

1172{
1173 BYTE rgbDig[256], *prgbDig;
1174 NUMPARSE np;
1175 int have_int, need_int = 0, have_frac, need_frac, exponent = 0, pad = 0;
1176 WCHAR buff[256], *pBuff = buff;
1177 WCHAR thousandSeparator[32];
1178 VARIANT vString, vBool;
1179 DWORD dwState = 0;
1180 FMT_HEADER *header = (FMT_HEADER*)rgbTok;
1181 FMT_NUMBER_HEADER *numHeader;
1182 const BYTE* pToken = NULL;
1183 HRESULT hRes = S_OK;
1184
1185 TRACE("(%s,%s,%p,0x%08x,%p,0x%08x)\n", debugstr_variant(pVarIn), debugstr_w(lpszFormat),
1186 rgbTok, dwFlags, pbstrOut, lcid);
1187
1188 V_VT(&vString) = VT_EMPTY;
1189 V_VT(&vBool) = VT_BOOL;
1190
1191 if (V_TYPE(pVarIn) == VT_EMPTY || V_TYPE(pVarIn) == VT_NULL)
1192 {
1193 have_int = have_frac = 0;
1194 numHeader = (FMT_NUMBER_HEADER*)(rgbTok + FmtGetNull(header));
1195 V_BOOL(&vBool) = VARIANT_FALSE;
1196 }
1197 else
1198 {
1199 /* Get a number string from pVarIn, and parse it */
1200 hRes = VariantChangeTypeEx(&vString, pVarIn, lcid, VARIANT_NOUSEROVERRIDE, VT_BSTR);
1201 if (FAILED(hRes))
1202 return hRes;
1203
1204 np.cDig = sizeof(rgbDig);
1205 np.dwInFlags = NUMPRS_STD;
1206 hRes = VarParseNumFromStr(V_BSTR(&vString), lcid, 0, &np, rgbDig);
1207 if (FAILED(hRes))
1208 return hRes;
1209
1210 have_int = np.cDig;
1211 have_frac = 0;
1212 exponent = np.nPwr10;
1213
1214 /* Figure out which format to use */
1215 if (np.dwOutFlags & NUMPRS_NEG)
1216 {
1217 numHeader = (FMT_NUMBER_HEADER*)(rgbTok + FmtGetNegative(header));
1218 V_BOOL(&vBool) = VARIANT_TRUE;
1219 }
1220 else if (have_int == 1 && !exponent && rgbDig[0] == 0)
1221 {
1222 numHeader = (FMT_NUMBER_HEADER*)(rgbTok + FmtGetZero(header));
1223 V_BOOL(&vBool) = VARIANT_FALSE;
1224 }
1225 else
1226 {
1227 numHeader = (FMT_NUMBER_HEADER*)(rgbTok + FmtGetPositive(header));
1228 V_BOOL(&vBool) = VARIANT_TRUE;
1229 }
1230
1231 TRACE("num header: flags = 0x%x, mult=%d, div=%d, whole=%d, fract=%d\n",
1232 numHeader->flags, numHeader->multiplier, numHeader->divisor,
1233 numHeader->whole, numHeader->fractional);
1234
1235 need_int = numHeader->whole;
1236 need_frac = numHeader->fractional;
1237
1238 if (numHeader->flags & FMT_FLAG_PERCENT &&
1239 !(have_int == 1 && !exponent && rgbDig[0] == 0))
1240 exponent += 2;
1241
1242 if (numHeader->flags & FMT_FLAG_EXPONENT)
1243 {
1244 /* Exponent format: length of the integral number part is fixed and
1245 specified by the format. */
1246 pad = need_int - have_int;
1247 exponent -= pad;
1248 if (pad < 0)
1249 {
1250 have_int = need_int;
1251 have_frac -= pad;
1252 pad = 0;
1253 }
1254 }
1255 else
1256 {
1257 /* Convert the exponent */
1258 pad = max(exponent, -have_int);
1259 exponent -= pad;
1260 if (pad < 0)
1261 {
1262 have_int += pad;
1263 have_frac = -pad;
1264 pad = 0;
1265 }
1266 if(exponent < 0 && exponent > (-256 + have_int + have_frac))
1267 {
1268 /* Remove exponent notation */
1269 memmove(rgbDig - exponent, rgbDig, have_int + have_frac);
1270 ZeroMemory(rgbDig, -exponent);
1271 have_frac -= exponent;
1272 exponent = 0;
1273 }
1274 }
1275
1276 /* Rounding the number */
1277 if (have_frac > need_frac)
1278 {
1279 prgbDig = &rgbDig[have_int + need_frac];
1280 have_frac = need_frac;
1281 if (*prgbDig >= 5)
1282 {
1283 while (prgbDig-- > rgbDig && *prgbDig == 9)
1284 *prgbDig = 0;
1285 if (prgbDig < rgbDig)
1286 {
1287 /* We reached the first digit and that was also a 9 */
1288 rgbDig[0] = 1;
1289 if (numHeader->flags & FMT_FLAG_EXPONENT)
1290 exponent++;
1291 else
1292 {
1293 rgbDig[have_int + need_frac] = 0;
1294 if (exponent < 0)
1295 exponent++;
1296 else
1297 have_int++;
1298 }
1299 }
1300 else
1301 (*prgbDig)++;
1302 }
1303 /* We converted trailing digits to zeroes => have_frac has changed */
1304 while (have_frac > 0 && rgbDig[have_int + have_frac - 1] == 0)
1305 have_frac--;
1306 }
1307 TRACE("have_int=%d,need_int=%d,have_frac=%d,need_frac=%d,pad=%d,exp=%d\n",
1308 have_int, need_int, have_frac, need_frac, pad, exponent);
1309 }
1310
1311 if (numHeader->flags & FMT_FLAG_THOUSANDS)
1312 {
1313 if (!GetLocaleInfoW(lcid, LOCALE_STHOUSAND, thousandSeparator, ARRAY_SIZE(thousandSeparator)))
1314 {
1315 thousandSeparator[0] = ',';
1316 thousandSeparator[1] = 0;
1317 }
1318 }
1319
1320 pToken = (const BYTE*)numHeader + sizeof(FMT_NUMBER_HEADER);
1321 prgbDig = rgbDig;
1322
1323 while (SUCCEEDED(hRes) && *pToken != FMT_GEN_END)
1324 {
1325 WCHAR defaultChar = '?';
1326 DWORD boolFlag, localeValue = 0;
1327 BOOL shouldAdvance = TRUE;
1328
1329 if (pToken - rgbTok > header->size)
1330 {
1331 ERR("Ran off the end of the format!\n");
1332 hRes = E_INVALIDARG;
1333 goto VARIANT_FormatNumber_Exit;
1334 }
1335
1336 switch (*pToken)
1337 {
1338 case FMT_GEN_COPY:
1339 TRACE("copy %s\n", debugstr_wn(lpszFormat + pToken[1], pToken[2]));
1340 memcpy(pBuff, lpszFormat + pToken[1], pToken[2] * sizeof(WCHAR));
1341 pBuff += pToken[2];
1342 pToken += 2;
1343 break;
1344
1345 case FMT_GEN_INLINE:
1346 pToken += 2;
1347 TRACE("copy %s\n", debugstr_a((LPCSTR)pToken));
1348 while (*pToken)
1349 *pBuff++ = *pToken++;
1350 break;
1351
1352 case FMT_NUM_YES_NO:
1353 boolFlag = VAR_BOOLYESNO;
1354 goto VARIANT_FormatNumber_Bool;
1355
1356 case FMT_NUM_ON_OFF:
1357 boolFlag = VAR_BOOLONOFF;
1358 goto VARIANT_FormatNumber_Bool;
1359
1360 case FMT_NUM_TRUE_FALSE:
1361 boolFlag = VAR_LOCALBOOL;
1362
1363VARIANT_FormatNumber_Bool:
1364 {
1365 BSTR boolStr = NULL;
1366
1367 if (pToken[1] != FMT_GEN_END)
1368 {
1369 ERR("Boolean token not at end of format!\n");
1370 hRes = E_INVALIDARG;
1371 goto VARIANT_FormatNumber_Exit;
1372 }
1373 hRes = VarBstrFromBool(V_BOOL(&vBool), lcid, boolFlag, &boolStr);
1374 if (SUCCEEDED(hRes))
1375 {
1376 lstrcpyW(pBuff, boolStr);
1377 SysFreeString(boolStr);
1378 while (*pBuff)
1379 pBuff++;
1380 }
1381 }
1382 break;
1383
1384 case FMT_NUM_DECIMAL:
1385 if ((np.dwOutFlags & NUMPRS_NEG) && !(dwState & NUM_WROTE_SIGN) && !header->starts[1])
1386 {
1387 /* last chance for a negative sign in the .# case */
1388 TRACE("write negative sign\n");
1389 localeValue = LOCALE_SNEGATIVESIGN;
1390 defaultChar = '-';
1391 dwState |= NUM_WROTE_SIGN;
1392 shouldAdvance = FALSE;
1393 break;
1394 }
1395 TRACE("write decimal separator\n");
1396 localeValue = LOCALE_SDECIMAL;
1397 defaultChar = '.';
1398 dwState |= NUM_WROTE_DEC;
1399 break;
1400
1401 case FMT_NUM_CURRENCY:
1402 TRACE("write currency symbol\n");
1403 localeValue = LOCALE_SCURRENCY;
1404 defaultChar = '$';
1405 break;
1406
1407 case FMT_NUM_EXP_POS_U:
1408 case FMT_NUM_EXP_POS_L:
1409 case FMT_NUM_EXP_NEG_U:
1410 case FMT_NUM_EXP_NEG_L:
1411 if (*pToken == FMT_NUM_EXP_POS_L || *pToken == FMT_NUM_EXP_NEG_L)
1412 *pBuff++ = 'e';
1413 else
1414 *pBuff++ = 'E';
1415 if (exponent < 0)
1416 {
1417 *pBuff++ = '-';
1418 swprintf(pBuff, szPercentZeroStar_d, pToken[1], -exponent);
1419 }
1420 else
1421 {
1422 if (*pToken == FMT_NUM_EXP_POS_L || *pToken == FMT_NUM_EXP_POS_U)
1423 *pBuff++ = '+';
1424 swprintf(pBuff, szPercentZeroStar_d, pToken[1], exponent);
1425 }
1426 while (*pBuff)
1427 pBuff++;
1428 pToken++;
1429 break;
1430
1431 case FMT_NUM_COPY_ZERO:
1432 dwState |= NUM_WRITE_ON;
1433 /* Fall through */
1434
1435 case FMT_NUM_COPY_SKIP:
1436 TRACE("write %d %sdigits or %s\n", pToken[1],
1437 dwState & NUM_WROTE_DEC ? "fractional " : "",
1438 *pToken == FMT_NUM_COPY_ZERO ? "0" : "skip");
1439
1440 if (dwState & NUM_WROTE_DEC)
1441 {
1442 int count, i;
1443
1444 if (!(numHeader->flags & FMT_FLAG_EXPONENT) && exponent < 0)
1445 {
1446 /* Pad with 0 before writing the fractional digits */
1447 pad = max(exponent, -pToken[1]);
1448 exponent -= pad;
1449 count = min(have_frac, pToken[1] + pad);
1450 for (i = 0; i > pad; i--)
1451 *pBuff++ = '0';
1452 }
1453 else
1454 count = min(have_frac, pToken[1]);
1455
1456 pad += pToken[1] - count;
1457 have_frac -= count;
1458 while (count--)
1459 *pBuff++ = '0' + *prgbDig++;
1460 if (*pToken == FMT_NUM_COPY_ZERO)
1461 {
1462 for (; pad > 0; pad--)
1463 *pBuff++ = '0'; /* Write zeros for missing trailing digits */
1464 }
1465 }
1466 else
1467 {
1468 int count, count_max, position;
1469
1470 if ((np.dwOutFlags & NUMPRS_NEG) && !(dwState & NUM_WROTE_SIGN) && !header->starts[1])
1471 {
1472 TRACE("write negative sign\n");
1473 localeValue = LOCALE_SNEGATIVESIGN;
1474 defaultChar = '-';
1475 dwState |= NUM_WROTE_SIGN;
1476 shouldAdvance = FALSE;
1477 break;
1478 }
1479
1480 position = have_int + pad;
1481 if (dwState & NUM_WRITE_ON)
1482 position = max(position, need_int);
1483 need_int -= pToken[1];
1484 count_max = have_int + pad - need_int;
1485 if (count_max < 0)
1486 count_max = 0;
1487 if (dwState & NUM_WRITE_ON)
1488 {
1489 count = pToken[1] - count_max;
1490 TRACE("write %d leading zeros\n", count);
1491 while (count-- > 0)
1492 {
1493 *pBuff++ = '0';
1494 if ((numHeader->flags & FMT_FLAG_THOUSANDS) &&
1495 position > 1 && (--position % 3) == 0)
1496 {
1497 int k;
1498 TRACE("write thousand separator\n");
1499 for (k = 0; thousandSeparator[k]; k++)
1500 *pBuff++ = thousandSeparator[k];
1501 }
1502 }
1503 }
1504 if (*pToken == FMT_NUM_COPY_ZERO || have_int > 1 ||
1505 (have_int > 0 && *prgbDig > 0))
1506 {
1507 count = min(count_max, have_int);
1508 count_max -= count;
1509 have_int -= count;
1510 TRACE("write %d whole number digits\n", count);
1511 while (count--)
1512 {
1513 dwState |= NUM_WRITE_ON;
1514 *pBuff++ = '0' + *prgbDig++;
1515 if ((numHeader->flags & FMT_FLAG_THOUSANDS) &&
1516 position > 1 && (--position % 3) == 0)
1517 {
1518 int k;
1519 TRACE("write thousand separator\n");
1520 for (k = 0; thousandSeparator[k]; k++)
1521 *pBuff++ = thousandSeparator[k];
1522 }
1523 }
1524 }
1525 count = min(count_max, pad);
1526 pad -= count;
1527 TRACE("write %d whole trailing 0's\n", count);
1528 while (count--)
1529 {
1530 *pBuff++ = '0';
1531 if ((numHeader->flags & FMT_FLAG_THOUSANDS) &&
1532 position > 1 && (--position % 3) == 0)
1533 {
1534 int k;
1535 TRACE("write thousand separator\n");
1536 for (k = 0; thousandSeparator[k]; k++)
1537 *pBuff++ = thousandSeparator[k];
1538 }
1539 }
1540 }
1541 pToken++;
1542 break;
1543
1544 default:
1545 ERR("Unknown token 0x%02x!\n", *pToken);
1546 hRes = E_INVALIDARG;
1547 goto VARIANT_FormatNumber_Exit;
1548 }
1549 if (localeValue)
1550 {
1551 if (GetLocaleInfoW(lcid, localeValue, pBuff, ARRAY_SIZE(buff)-(pBuff-buff)))
1552 {
1553 TRACE("added %s\n", debugstr_w(pBuff));
1554 while (*pBuff)
1555 pBuff++;
1556 }
1557 else
1558 {
1559 TRACE("added %d '%c'\n", defaultChar, defaultChar);
1560 *pBuff++ = defaultChar;
1561 }
1562 }
1563 if (shouldAdvance)
1564 pToken++;
1565 }
1566
1567VARIANT_FormatNumber_Exit:
1568 VariantClear(&vString);
1569 *pBuff = '\0';
1570 TRACE("buff is %s\n", debugstr_w(buff));
1571 if (SUCCEEDED(hRes))
1572 {
1573 *pbstrOut = SysAllocString(buff);
1574 if (!*pbstrOut)
1575 hRes = E_OUTOFMEMORY;
1576 }
1577 return hRes;
1578}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
@ VT_BOOL
Definition: compat.h:2306
#define FMT_NUM_COPY_SKIP
Definition: varformat.c:261
#define FMT_NUM_EXP_POS_L
Definition: varformat.c:265
#define FMT_NUM_EXP_NEG_U
Definition: varformat.c:264
#define FmtGetZero(x)
Definition: varformat.c:166
#define FMT_NUM_CURRENCY
Definition: varformat.c:267
#define FMT_FLAG_EXPONENT
Definition: varformat.c:191
#define FMT_NUM_DECIMAL
Definition: varformat.c:262
#define NUM_WROTE_SIGN
Definition: varformat.c:1166
#define FMT_FLAG_THOUSANDS
Definition: varformat.c:192
#define FMT_NUM_TRUE_FALSE
Definition: varformat.c:268
#define FMT_FLAG_PERCENT
Definition: varformat.c:190
static const WCHAR szPercentZeroStar_d[]
Definition: varformat.c:49
#define FMT_NUM_EXP_POS_U
Definition: varformat.c:263
#define FMT_NUM_YES_NO
Definition: varformat.c:269
#define NUM_WROTE_DEC
Definition: varformat.c:1164
#define NUM_WRITE_ON
Definition: varformat.c:1165
#define FMT_NUM_ON_OFF
Definition: varformat.c:270
#define FmtGetNull(x)
Definition: varformat.c:167
#define FMT_NUM_COPY_ZERO
Definition: varformat.c:260
#define FMT_NUM_EXP_NEG_L
Definition: varformat.c:266
HRESULT WINAPI VarBstrFromBool(VARIANT_BOOL boolIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:6852
GLuint GLuint GLsizei count
Definition: gl.h:1545
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
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define min(a, b)
Definition: monoChain.cc:55
int k
Definition: mpi.c:3369
#define V_BOOL(A)
Definition: oleauto.h:224
#define NUMPRS_NEG
Definition: oleauto.h:749
#define VARIANT_NOUSEROVERRIDE
Definition: oleauto.h:312
#define VAR_LOCALBOOL
Definition: oleauto.h:330
#define NUMPRS_STD
Definition: oleauto.h:748
ULONG dwInFlags
Definition: oleauto.h:728
INT cDig
Definition: oleauto.h:727
ULONG dwOutFlags
Definition: oleauto.h:729
INT nPwr10
Definition: oleauto.h:732
#define max(a, b)
Definition: svc.c:63
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
HRESULT WINAPI VarParseNumFromStr(OLECHAR *lpszStr, LCID lcid, ULONG dwFlags, NUMPARSE *pNumprs, BYTE *rgbDig)
Definition: variant.c:1604
#define VAR_BOOLONOFF
Definition: variant.h:102
#define VAR_BOOLYESNO
Definition: variant.h:103
#define ZeroMemory
Definition: winbase.h:1737
#define LOCALE_SNEGATIVESIGN
Definition: winnls.h:120

Referenced by VarFormatFromTokens().

◆ VARIANT_FormatString()

static HRESULT VARIANT_FormatString ( LPVARIANT  pVarIn,
LPOLESTR  lpszFormat,
LPBYTE  rgbTok,
ULONG  dwFlags,
BSTR pbstrOut,
LCID  lcid 
)
static

Definition at line 1917 of file varformat.c.

1920{
1921 static WCHAR szEmpty[] = { '\0' };
1922 WCHAR buff[256], *pBuff = buff;
1923 WCHAR *pSrc;
1924 FMT_HEADER *header = (FMT_HEADER*)rgbTok;
1925 FMT_STRING_HEADER *strHeader;
1926 const BYTE* pToken = NULL;
1927 VARIANT vStr;
1928 int blanks_first;
1929 BOOL bUpper = FALSE;
1930 HRESULT hRes = S_OK;
1931
1932 TRACE("%s,%s,%p,0x%08x,%p,0x%08x)\n", debugstr_variant(pVarIn), debugstr_w(lpszFormat),
1933 rgbTok, dwFlags, pbstrOut, lcid);
1934
1935 V_VT(&vStr) = VT_EMPTY;
1936
1937 if (V_TYPE(pVarIn) == VT_EMPTY || V_TYPE(pVarIn) == VT_NULL)
1938 {
1939 strHeader = (FMT_STRING_HEADER*)(rgbTok + FmtGetNegative(header));
1940 V_BSTR(&vStr) = szEmpty;
1941 }
1942 else
1943 {
1944 hRes = VariantChangeTypeEx(&vStr, pVarIn, lcid, VARIANT_NOUSEROVERRIDE, VT_BSTR);
1945 if (FAILED(hRes))
1946 return hRes;
1947
1948 if (V_BSTR(&vStr)[0] == '\0')
1949 strHeader = (FMT_STRING_HEADER*)(rgbTok + FmtGetNegative(header));
1950 else
1951 strHeader = (FMT_STRING_HEADER*)(rgbTok + FmtGetPositive(header));
1952 }
1953 pSrc = V_BSTR(&vStr);
1954 if ((strHeader->flags & (FMT_FLAG_LT|FMT_FLAG_GT)) == FMT_FLAG_GT)
1955 bUpper = TRUE;
1956 blanks_first = strHeader->copy_chars - lstrlenW(pSrc);
1957 pToken = (const BYTE*)strHeader + sizeof(FMT_DATE_HEADER);
1958
1959 while (*pToken != FMT_GEN_END)
1960 {
1961 int dwCount = 0;
1962
1963 if (pToken - rgbTok > header->size)
1964 {
1965 ERR("Ran off the end of the format!\n");
1966 hRes = E_INVALIDARG;
1967 goto VARIANT_FormatString_Exit;
1968 }
1969
1970 switch (*pToken)
1971 {
1972 case FMT_GEN_COPY:
1973 TRACE("copy %s\n", debugstr_wn(lpszFormat + pToken[1], pToken[2]));
1974 memcpy(pBuff, lpszFormat + pToken[1], pToken[2] * sizeof(WCHAR));
1975 pBuff += pToken[2];
1976 pToken += 2;
1977 break;
1978
1979 case FMT_STR_COPY_SPACE:
1980 case FMT_STR_COPY_SKIP:
1981 dwCount = pToken[1];
1982 if (*pToken == FMT_STR_COPY_SPACE && blanks_first > 0)
1983 {
1984 TRACE("insert %d initial spaces\n", blanks_first);
1985 while (dwCount > 0 && blanks_first > 0)
1986 {
1987 *pBuff++ = ' ';
1988 dwCount--;
1989 blanks_first--;
1990 }
1991 }
1992 TRACE("copy %d chars%s\n", dwCount,
1993 *pToken == FMT_STR_COPY_SPACE ? " with space" :"");
1994 while (dwCount > 0 && *pSrc)
1995 {
1996 if (bUpper)
1997 *pBuff++ = towupper(*pSrc);
1998 else
1999 *pBuff++ = towlower(*pSrc);
2000 dwCount--;
2001 pSrc++;
2002 }
2003 if (*pToken == FMT_STR_COPY_SPACE && dwCount > 0)
2004 {
2005 TRACE("insert %d spaces\n", dwCount);
2006 while (dwCount-- > 0)
2007 *pBuff++ = ' ';
2008 }
2009 pToken++;
2010 break;
2011
2012 default:
2013 ERR("Unknown token 0x%02x!\n", *pToken);
2014 hRes = E_INVALIDARG;
2015 goto VARIANT_FormatString_Exit;
2016 }
2017 pToken++;
2018 }
2019
2020VARIANT_FormatString_Exit:
2021 /* Copy out any remaining chars */
2022 while (*pSrc)
2023 {
2024 if (bUpper)
2025 *pBuff++ = towupper(*pSrc);
2026 else
2027 *pBuff++ = towlower(*pSrc);
2028 pSrc++;
2029 }
2030 VariantClear(&vStr);
2031 *pBuff = '\0';
2032 TRACE("buff is %s\n", debugstr_w(buff));
2033 if (SUCCEEDED(hRes))
2034 {
2035 *pbstrOut = SysAllocString(buff);
2036 if (!*pbstrOut)
2037 hRes = E_OUTOFMEMORY;
2038 }
2039 return hRes;
2040}
#define FMT_STR_COPY_SPACE
Definition: varformat.c:271
#define FMT_FLAG_LT
Definition: varformat.c:173
#define FMT_STR_COPY_SKIP
Definition: varformat.c:272
#define FMT_FLAG_GT
Definition: varformat.c:174
#define towlower(c)
Definition: wctype.h:97
#define towupper(c)
Definition: wctype.h:99

Referenced by VarFormatFromTokens().

◆ VARIANT_GetNamedFormat()

static const BYTE * VARIANT_GetNamedFormat ( LPCWSTR  lpszFormat)
inlinestatic

Definition at line 443 of file varformat.c.

444{
447
448 key.name = lpszFormat;
451 return fmt ? fmt->format : NULL;
452}
static const NAMED_FORMAT VARIANT_NamedFormats[]
Definition: varformat.c:417
static int __cdecl FormatCompareFn(const void *l, const void *r)
Definition: varformat.c:438
Definition: dsound.c:943
Definition: copy.c:22
WCHAR * name
Definition: path.c:43
#define bsearch

Referenced by VarTokenizeFormatString().

◆ VarMonthName()

HRESULT WINAPI VarMonthName ( INT  iMonth,
INT  fAbbrev,
ULONG  dwFlags,
BSTR pbstrOut 
)

Definition at line 2517 of file varformat.c.

2518{
2519 DWORD localeValue;
2520 INT size;
2521
2522 if ((iMonth < 1) || (iMonth > 12))
2523 return E_INVALIDARG;
2524
2525 if (dwFlags)
2526 FIXME("Does not support dwFlags 0x%x, ignoring.\n", dwFlags);
2527
2528 if (fAbbrev)
2529 localeValue = LOCALE_SABBREVMONTHNAME1 + iMonth - 1;
2530 else
2531 localeValue = LOCALE_SMONTHNAME1 + iMonth - 1;
2532
2533 size = GetLocaleInfoW(LOCALE_USER_DEFAULT,localeValue, NULL, 0);
2534 if (!size) {
2535 ERR("GetLocaleInfo 0x%x failed.\n", localeValue);
2537 }
2538 *pbstrOut = SysAllocStringLen(NULL,size - 1);
2539 if (!*pbstrOut)
2540 return E_OUTOFMEMORY;
2541 size = GetLocaleInfoW(LOCALE_USER_DEFAULT,localeValue, *pbstrOut, size);
2542 if (!size) {
2543 ERR("GetLocaleInfo of 0x%x failed in 2nd stage?!\n", localeValue);
2544 SysFreeString(*pbstrOut);
2546 }
2547 return S_OK;
2548}
GLsizeiptr size
Definition: glext.h:5919
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
int32_t INT
Definition: typedefs.h:58
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92

Referenced by Global_MonthName().

◆ VarTokenizeFormatString()

HRESULT WINAPI VarTokenizeFormatString ( LPOLESTR  lpszFormat,
LPBYTE  rgbTok,
int  cbTok,
int  nFirstDay,
int  nFirstWeek,
LCID  lcid,
int pcbActual 
)

Definition at line 495 of file varformat.c.

498{
499 /* Note: none of these strings should be NUL terminated */
500 static const WCHAR szTTTTT[] = { 't','t','t','t','t' };
501 static const WCHAR szAMPM[] = { 'A','M','P','M' };
502 static const WCHAR szampm[] = { 'a','m','p','m' };
503 static const WCHAR szAMSlashPM[] = { 'A','M','/','P','M' };
504 static const WCHAR szamSlashpm[] = { 'a','m','/','p','m' };
505 const BYTE *namedFmt;
506 FMT_HEADER *header = (FMT_HEADER*)rgbTok;
507 FMT_STRING_HEADER *str_header = (FMT_STRING_HEADER*)(rgbTok + sizeof(FMT_HEADER));
508 FMT_NUMBER_HEADER *num_header = (FMT_NUMBER_HEADER*)str_header;
509 BYTE* pOut = rgbTok + sizeof(FMT_HEADER) + sizeof(FMT_STRING_HEADER);
510 BYTE* pLastHours = NULL;
511 BYTE fmt_number = 0;
512 DWORD fmt_state = 0;
513 LPCWSTR pFormat = lpszFormat;
514
515 TRACE("(%s,%p,%d,%d,%d,0x%08x,%p)\n", debugstr_w(lpszFormat), rgbTok, cbTok,
516 nFirstDay, nFirstWeek, lcid, pcbActual);
517
518 if (!rgbTok ||
519 nFirstDay < 0 || nFirstDay > 7 || nFirstWeek < 0 || nFirstWeek > 3)
520 return E_INVALIDARG;
521
522 if (!lpszFormat || !*lpszFormat)
523 {
524 /* An empty string means 'general format' */
525 NEED_SPACE(sizeof(BYTE));
526 *rgbTok = FMT_TO_STRING;
527 if (pcbActual)
528 *pcbActual = FMT_TO_STRING;
529 return S_OK;
530 }
531
532 if (cbTok > 255)
533 cbTok = 255; /* Ensure we error instead of wrapping */
534
535 /* Named formats */
536 namedFmt = VARIANT_GetNamedFormat(lpszFormat);
537 if (namedFmt)
538 {
539 NEED_SPACE(namedFmt[0]);
540 memcpy(rgbTok, namedFmt, namedFmt[0]);
541 TRACE("Using pre-tokenised named format %s\n", debugstr_w(lpszFormat));
542 /* FIXME: pcbActual */
543 return S_OK;
544 }
545
546 /* Insert header */
547 NEED_SPACE(sizeof(FMT_HEADER) + sizeof(FMT_STRING_HEADER));
548 memset(header, 0, sizeof(FMT_HEADER));
549 memset(str_header, 0, sizeof(FMT_STRING_HEADER));
550
551 header->starts[fmt_number] = sizeof(FMT_HEADER);
552
553 while (*pFormat)
554 {
555 /* --------------
556 * General tokens
557 * --------------
558 */
559 if (*pFormat == ';')
560 {
561 while (*pFormat == ';')
562 {
563 TRACE(";\n");
564 if (++fmt_number > 3)
565 return E_INVALIDARG; /* too many formats */
566 pFormat++;
567 }
568 if (*pFormat)
569 {
570 TRACE("New header\n");
571 NEED_SPACE(sizeof(BYTE) + sizeof(FMT_STRING_HEADER));
572 *pOut++ = FMT_GEN_END;
573
574 header->starts[fmt_number] = pOut - rgbTok;
575 str_header = (FMT_STRING_HEADER*)pOut;
576 num_header = (FMT_NUMBER_HEADER*)pOut;
577 memset(str_header, 0, sizeof(FMT_STRING_HEADER));
578 pOut += sizeof(FMT_STRING_HEADER);
579 fmt_state = 0;
580 pLastHours = NULL;
581 }
582 }
583 else if (*pFormat == '\\')
584 {
585 /* Escaped character */
586 if (pFormat[1])
587 {
588 NEED_SPACE(3 * sizeof(BYTE));
589 pFormat++;
590 *pOut++ = FMT_GEN_COPY;
591 *pOut++ = pFormat - lpszFormat;
592 *pOut++ = 0x1;
593 fmt_state |= FMT_STATE_OPEN_COPY;
594 TRACE("'\\'\n");
595 }
596 else
597 fmt_state &= ~FMT_STATE_OPEN_COPY;
598 pFormat++;
599 }
600 else if (*pFormat == '"')
601 {
602 /* Escaped string
603 * Note: Native encodes "" as a copy of length zero. That's just dumb, so
604 * here we avoid encoding anything in this case.
605 */
606 if (!pFormat[1])
607 pFormat++;
608 else if (pFormat[1] == '"')
609 {
610 pFormat += 2;
611 }
612 else
613 {
614 LPCWSTR start = ++pFormat;
615 while (*pFormat && *pFormat != '"')
616 pFormat++;
617 NEED_SPACE(3 * sizeof(BYTE));
618 *pOut++ = FMT_GEN_COPY;
619 *pOut++ = start - lpszFormat;
620 *pOut++ = pFormat - start;
621 if (*pFormat == '"')
622 pFormat++;
623 TRACE("Quoted string pos %d, len %d\n", pOut[-2], pOut[-1]);
624 }
625 fmt_state &= ~FMT_STATE_OPEN_COPY;
626 }
627 /* -------------
628 * Number tokens
629 * -------------
630 */
631 else if (*pFormat == '0' && COULD_BE(FMT_TYPE_NUMBER))
632 {
633 /* Number formats: Digit from number or '0' if no digits
634 * Other formats: Literal
635 * Types the format if found
636 */
637 header->type = FMT_TYPE_NUMBER;
638 NEED_SPACE(2 * sizeof(BYTE));
639 *pOut++ = FMT_NUM_COPY_ZERO;
640 *pOut = 0x0;
641 while (*pFormat == '0')
642 {
643 *pOut = *pOut + 1;
644 pFormat++;
645 }
646 if (fmt_state & FMT_STATE_WROTE_DECIMAL)
647 num_header->fractional += *pOut;
648 else
649 num_header->whole += *pOut;
650 TRACE("%d 0's\n", *pOut);
651 pOut++;
652 fmt_state &= ~FMT_STATE_OPEN_COPY;
653 }
654 else if (*pFormat == '#' && COULD_BE(FMT_TYPE_NUMBER))
655 {
656 /* Number formats: Digit from number or blank if no digits
657 * Other formats: Literal
658 * Types the format if found
659 */
660 header->type = FMT_TYPE_NUMBER;
661 NEED_SPACE(2 * sizeof(BYTE));
662 *pOut++ = FMT_NUM_COPY_SKIP;
663 *pOut = 0x0;
664 while (*pFormat == '#')
665 {
666 *pOut = *pOut + 1;
667 pFormat++;
668 }
669 if (fmt_state & FMT_STATE_WROTE_DECIMAL)
670 num_header->fractional += *pOut;
671 else
672 num_header->whole += *pOut;
673 TRACE("%d #'s\n", *pOut);
674 pOut++;
675 fmt_state &= ~FMT_STATE_OPEN_COPY;
676 }
677 else if (*pFormat == '.' && COULD_BE(FMT_TYPE_NUMBER) &&
678 !(fmt_state & FMT_STATE_WROTE_DECIMAL))
679 {
680 /* Number formats: Decimal separator when 1st seen, literal thereafter
681 * Other formats: Literal
682 * Types the format if found
683 */
684 header->type = FMT_TYPE_NUMBER;
685 NEED_SPACE(sizeof(BYTE));
686 *pOut++ = FMT_NUM_DECIMAL;
687 fmt_state |= FMT_STATE_WROTE_DECIMAL;
688 fmt_state &= ~FMT_STATE_OPEN_COPY;
689 pFormat++;
690 TRACE("decimal sep\n");
691 }
692 else if ((*pFormat == 'e' || *pFormat == 'E') && (pFormat[1] == '-' ||
693 pFormat[1] == '+') && header->type == FMT_TYPE_NUMBER)
694 {
695 /* Number formats: Exponent specifier
696 * Other formats: Literal
697 */
698 num_header->flags |= FMT_FLAG_EXPONENT;
699 NEED_SPACE(2 * sizeof(BYTE));
700 if (*pFormat == 'e') {
701 if (pFormat[1] == '+')
702 *pOut = FMT_NUM_EXP_POS_L;
703 else
704 *pOut = FMT_NUM_EXP_NEG_L;
705 } else {
706 if (pFormat[1] == '+')
707 *pOut = FMT_NUM_EXP_POS_U;
708 else
709 *pOut = FMT_NUM_EXP_NEG_U;
710 }
711 pFormat += 2;
712 *++pOut = 0x0;
713 while (*pFormat == '0')
714 {
715 *pOut = *pOut + 1;
716 pFormat++;
717 }
718 pOut++;
719 TRACE("exponent\n");
720 }
721 /* FIXME: %% => Divide by 1000 */
722 else if (*pFormat == ',' && header->type == FMT_TYPE_NUMBER)
723 {
724 /* Number formats: Use the thousands separator
725 * Other formats: Literal
726 */
727 num_header->flags |= FMT_FLAG_THOUSANDS;
728 pFormat++;
729 fmt_state &= ~FMT_STATE_OPEN_COPY;
730 TRACE("thousands sep\n");
731 }
732 /* -----------
733 * Date tokens
734 * -----------
735 */
736 else if (*pFormat == '/' && COULD_BE(FMT_TYPE_DATE))
737 {
738 /* Date formats: Date separator
739 * Other formats: Literal
740 * Types the format if found
741 */
742 header->type = FMT_TYPE_DATE;
743 NEED_SPACE(sizeof(BYTE));
744 *pOut++ = FMT_DATE_DATE_SEP;
745 pFormat++;
746 fmt_state &= ~FMT_STATE_OPEN_COPY;
747 TRACE("date sep\n");
748 }
749 else if (*pFormat == ':' && COULD_BE(FMT_TYPE_DATE))
750 {
751 /* Date formats: Time separator
752 * Other formats: Literal
753 * Types the format if found
754 */
755 header->type = FMT_TYPE_DATE;
756 NEED_SPACE(sizeof(BYTE));
757 *pOut++ = FMT_DATE_TIME_SEP;
758 pFormat++;
759 fmt_state &= ~FMT_STATE_OPEN_COPY;
760 TRACE("time sep\n");
761 }
762 else if ((*pFormat == 'a' || *pFormat == 'A') &&
763 !_wcsnicmp(pFormat, szAMPM, ARRAY_SIZE(szAMPM)))
764 {
765 /* Date formats: System AM/PM designation
766 * Other formats: Literal
767 * Types the format if found
768 */
769 header->type = FMT_TYPE_DATE;
770 NEED_SPACE(sizeof(BYTE));
771 pFormat += ARRAY_SIZE(szAMPM);
772 if (!wcsncmp(pFormat, szampm, ARRAY_SIZE(szampm)))
773 *pOut++ = FMT_DATE_AMPM_SYS2;
774 else
775 *pOut++ = FMT_DATE_AMPM_SYS1;
776 if (pLastHours)
777 *pLastHours = *pLastHours + 2;
778 TRACE("ampm\n");
779 }
780 else if (*pFormat == 'a' && pFormat[1] == '/' &&
781 (pFormat[2] == 'p' || pFormat[2] == 'P'))
782 {
783 /* Date formats: lowercase a or p designation
784 * Other formats: Literal
785 * Types the format if found
786 */
787 header->type = FMT_TYPE_DATE;
788 NEED_SPACE(sizeof(BYTE));
789 pFormat += 3;
790 *pOut++ = FMT_DATE_A_LOWER;
791 if (pLastHours)
792 *pLastHours = *pLastHours + 2;
793 TRACE("a/p\n");
794 }
795 else if (*pFormat == 'A' && pFormat[1] == '/' &&
796 (pFormat[2] == 'p' || pFormat[2] == 'P'))
797 {
798 /* Date formats: Uppercase a or p designation
799 * Other formats: Literal
800 * Types the format if found
801 */
802 header->type = FMT_TYPE_DATE;
803 NEED_SPACE(sizeof(BYTE));
804 pFormat += 3;
805 *pOut++ = FMT_DATE_A_UPPER;
806 if (pLastHours)
807 *pLastHours = *pLastHours + 2;
808 TRACE("A/P\n");
809 }
810 else if (*pFormat == 'a' && !wcsncmp(pFormat, szamSlashpm, ARRAY_SIZE(szamSlashpm)))
811 {
812 /* Date formats: lowercase AM or PM designation
813 * Other formats: Literal
814 * Types the format if found
815 */
816 header->type = FMT_TYPE_DATE;
817 NEED_SPACE(sizeof(BYTE));
818 pFormat += ARRAY_SIZE(szamSlashpm);
819 *pOut++ = FMT_DATE_AMPM_LOWER;
820 if (pLastHours)
821 *pLastHours = *pLastHours + 2;
822 TRACE("AM/PM\n");
823 }
824 else if (*pFormat == 'A' && !wcsncmp(pFormat, szAMSlashPM, ARRAY_SIZE(szAMSlashPM)))
825 {
826 /* Date formats: Uppercase AM or PM designation
827 * Other formats: Literal
828 * Types the format if found
829 */
830 header->type = FMT_TYPE_DATE;
831 NEED_SPACE(sizeof(BYTE));
832 pFormat += ARRAY_SIZE(szAMSlashPM);
833 *pOut++ = FMT_DATE_AMPM_UPPER;
834 TRACE("AM/PM\n");
835 }
836 else if ((*pFormat == 'c' || *pFormat == 'C') && COULD_BE(FMT_TYPE_DATE))
837 {
838 /* Date formats: General date format
839 * Other formats: Literal
840 * Types the format if found
841 */
842 header->type = FMT_TYPE_DATE;
843 NEED_SPACE(sizeof(BYTE));
844 pFormat += ARRAY_SIZE(szAMSlashPM);
845 *pOut++ = FMT_DATE_GENERAL;
846 TRACE("gen date\n");
847 }
848 else if ((*pFormat == 'd' || *pFormat == 'D') && COULD_BE(FMT_TYPE_DATE))
849 {
850 /* Date formats: Day specifier
851 * Other formats: Literal
852 * Types the format if found
853 */
854 int count = -1;
855 header->type = FMT_TYPE_DATE;
856 while ((*pFormat == 'd' || *pFormat == 'D') && count < 6)
857 {
858 pFormat++;
859 count++;
860 }
861 NEED_SPACE(sizeof(BYTE));
862 *pOut++ = FMT_DATE_DAY + count;
863 fmt_state &= ~FMT_STATE_OPEN_COPY;
864 /* When we find the days token, reset the seen hours state so that
865 * 'mm' is again written as month when encountered.
866 */
867 fmt_state &= ~FMT_STATE_SEEN_HOURS;
868 TRACE("%d d's\n", count + 1);
869 }
870 else if ((*pFormat == 'h' || *pFormat == 'H') && COULD_BE(FMT_TYPE_DATE))
871 {
872 /* Date formats: Hour specifier
873 * Other formats: Literal
874 * Types the format if found
875 */
876 header->type = FMT_TYPE_DATE;
877 NEED_SPACE(sizeof(BYTE));
878 pFormat++;
879 /* Record the position of the hours specifier - if we encounter
880 * an am/pm specifier we will change the hours from 24 to 12.
881 */
882 pLastHours = pOut;
883 if (*pFormat == 'h' || *pFormat == 'H')
884 {
885 pFormat++;
886 *pOut++ = FMT_DATE_HOUR_0;
887 TRACE("hh\n");
888 }
889 else
890 {
891 *pOut++ = FMT_DATE_HOUR;
892 TRACE("h\n");
893 }
894 fmt_state &= ~FMT_STATE_OPEN_COPY;
895 /* Note that now we have seen an hours token, the next occurrence of
896 * 'mm' indicates minutes, not months.
897 */
898 fmt_state |= FMT_STATE_SEEN_HOURS;
899 }
900 else if ((*pFormat == 'm' || *pFormat == 'M') && COULD_BE(FMT_TYPE_DATE))
901 {
902 /* Date formats: Month specifier (or Minute specifier, after hour specifier)
903 * Other formats: Literal
904 * Types the format if found
905 */
906 int count = -1;
907 header->type = FMT_TYPE_DATE;
908 while ((*pFormat == 'm' || *pFormat == 'M') && count < 4)
909 {
910 pFormat++;
911 count++;
912 }
913 NEED_SPACE(sizeof(BYTE));
914 if (count <= 1 && fmt_state & FMT_STATE_SEEN_HOURS &&
915 !(fmt_state & FMT_STATE_WROTE_MINUTES))
916 {
917 /* We have seen an hours specifier and not yet written a minutes
918 * specifier. Write this as minutes and thereafter as months.
919 */
920 *pOut++ = count == 1 ? FMT_DATE_MIN_0 : FMT_DATE_MIN;
921 fmt_state |= FMT_STATE_WROTE_MINUTES; /* Hereafter write months */
922 }
923 else
924 *pOut++ = FMT_DATE_MON + count; /* Months */
925 fmt_state &= ~FMT_STATE_OPEN_COPY;
926 TRACE("%d m's\n", count + 1);
927 }
928 else if ((*pFormat == 'n' || *pFormat == 'N') && COULD_BE(FMT_TYPE_DATE))
929 {
930 /* Date formats: Minute specifier
931 * Other formats: Literal
932 * Types the format if found
933 */
934 header->type = FMT_TYPE_DATE;
935 NEED_SPACE(sizeof(BYTE));
936 pFormat++;
937 if (*pFormat == 'n' || *pFormat == 'N')
938 {
939 pFormat++;
940 *pOut++ = FMT_DATE_MIN_0;
941 TRACE("nn\n");
942 }
943 else
944 {
945 *pOut++ = FMT_DATE_MIN;
946 TRACE("n\n");
947 }
948 fmt_state &= ~FMT_STATE_OPEN_COPY;
949 }
950 else if ((*pFormat == 'q' || *pFormat == 'Q') && COULD_BE(FMT_TYPE_DATE))
951 {
952 /* Date formats: Quarter specifier
953 * Other formats: Literal
954 * Types the format if found
955 */
956 header->type = FMT_TYPE_DATE;
957 NEED_SPACE(sizeof(BYTE));
958 *pOut++ = FMT_DATE_QUARTER;
959 pFormat++;
960 fmt_state &= ~FMT_STATE_OPEN_COPY;
961 TRACE("quarter\n");
962 }
963 else if ((*pFormat == 's' || *pFormat == 'S') && COULD_BE(FMT_TYPE_DATE))
964 {
965 /* Date formats: Second specifier
966 * Other formats: Literal
967 * Types the format if found
968 */
969 header->type = FMT_TYPE_DATE;
970 NEED_SPACE(sizeof(BYTE));
971 pFormat++;
972 if (*pFormat == 's' || *pFormat == 'S')
973 {
974 pFormat++;
975 *pOut++ = FMT_DATE_SEC_0;
976 TRACE("ss\n");
977 }
978 else
979 {
980 *pOut++ = FMT_DATE_SEC;
981 TRACE("s\n");
982 }
983 fmt_state &= ~FMT_STATE_OPEN_COPY;
984 }
985 else if ((*pFormat == 't' || *pFormat == 'T') &&
986 !_wcsnicmp(pFormat, szTTTTT, ARRAY_SIZE(szTTTTT)))
987 {
988 /* Date formats: System time specifier
989 * Other formats: Literal
990 * Types the format if found
991 */
992 header->type = FMT_TYPE_DATE;
993 pFormat += ARRAY_SIZE(szTTTTT);
994 NEED_SPACE(sizeof(BYTE));
995 *pOut++ = FMT_DATE_TIME_SYS;
996 fmt_state &= ~FMT_STATE_OPEN_COPY;
997 }
998 else if ((*pFormat == 'w' || *pFormat == 'W') && COULD_BE(FMT_TYPE_DATE))
999 {
1000 /* Date formats: Week of the year/Day of the week
1001 * Other formats: Literal
1002 * Types the format if found
1003 */
1004 header->type = FMT_TYPE_DATE;
1005 pFormat++;
1006 if (*pFormat == 'w' || *pFormat == 'W')
1007 {
1008 NEED_SPACE(3 * sizeof(BYTE));
1009 pFormat++;
1010 *pOut++ = FMT_DATE_WEEK_YEAR;
1011 *pOut++ = nFirstDay;
1012 *pOut++ = nFirstWeek;
1013 TRACE("ww\n");
1014 }
1015 else
1016 {
1017 NEED_SPACE(2 * sizeof(BYTE));
1018 *pOut++ = FMT_DATE_DAY_WEEK;
1019 *pOut++ = nFirstDay;
1020 TRACE("w\n");
1021 }
1022
1023 fmt_state &= ~FMT_STATE_OPEN_COPY;
1024 }
1025 else if ((*pFormat == 'y' || *pFormat == 'Y') && COULD_BE(FMT_TYPE_DATE))
1026 {
1027 /* Date formats: Day of year/Year specifier
1028 * Other formats: Literal
1029 * Types the format if found
1030 */
1031 int count = -1;
1032 header->type = FMT_TYPE_DATE;
1033 while ((*pFormat == 'y' || *pFormat == 'Y') && count < 4)
1034 {
1035 pFormat++;
1036 count++;
1037 }
1038 if (count == 2)
1039 {
1040 count--; /* 'yyy' has no meaning, despite what MSDN says */
1041 pFormat--;
1042 }
1043 NEED_SPACE(sizeof(BYTE));
1044 *pOut++ = FMT_DATE_YEAR_DOY + count;
1045 fmt_state &= ~FMT_STATE_OPEN_COPY;
1046 TRACE("%d y's\n", count + 1);
1047 }
1048 /* -------------
1049 * String tokens
1050 * -------------
1051 */
1052 else if (*pFormat == '@' && COULD_BE(FMT_TYPE_STRING))
1053 {
1054 /* String formats: Character from string or space if no char
1055 * Other formats: Literal
1056 * Types the format if found
1057 */
1058 header->type = FMT_TYPE_STRING;
1059 NEED_SPACE(2 * sizeof(BYTE));
1060 *pOut++ = FMT_STR_COPY_SPACE;
1061 *pOut = 0x0;
1062 while (*pFormat == '@')
1063 {
1064 *pOut = *pOut + 1;
1065 str_header->copy_chars++;
1066 pFormat++;
1067 }
1068 TRACE("%d @'s\n", *pOut);
1069 pOut++;
1070 fmt_state &= ~FMT_STATE_OPEN_COPY;
1071 }
1072 else if (*pFormat == '&' && COULD_BE(FMT_TYPE_STRING))
1073 {
1074 /* String formats: Character from string or skip if no char
1075 * Other formats: Literal
1076 * Types the format if found
1077 */
1078 header->type = FMT_TYPE_STRING;
1079 NEED_SPACE(2 * sizeof(BYTE));
1080 *pOut++ = FMT_STR_COPY_SKIP;
1081 *pOut = 0x0;
1082 while (*pFormat == '&')
1083 {
1084 *pOut = *pOut + 1;
1085 str_header->copy_chars++;
1086 pFormat++;
1087 }
1088 TRACE("%d &'s\n", *pOut);
1089 pOut++;
1090 fmt_state &= ~FMT_STATE_OPEN_COPY;
1091 }
1092 else if ((*pFormat == '<' || *pFormat == '>') && COULD_BE(FMT_TYPE_STRING))
1093 {
1094 /* String formats: Use upper/lower case
1095 * Other formats: Literal
1096 * Types the format if found
1097 */
1098 header->type = FMT_TYPE_STRING;
1099 if (*pFormat == '<')
1100 str_header->flags |= FMT_FLAG_LT;
1101 else
1102 str_header->flags |= FMT_FLAG_GT;
1103 TRACE("to %s case\n", *pFormat == '<' ? "lower" : "upper");
1104 pFormat++;
1105 fmt_state &= ~FMT_STATE_OPEN_COPY;
1106 }
1107 else if (*pFormat == '!' && COULD_BE(FMT_TYPE_STRING))
1108 {
1109 /* String formats: Copy right to left
1110 * Other formats: Literal
1111 * Types the format if found
1112 */
1113 header->type = FMT_TYPE_STRING;
1114 str_header->flags |= FMT_FLAG_RTL;
1115 pFormat++;
1116 fmt_state &= ~FMT_STATE_OPEN_COPY;
1117 TRACE("copy right-to-left\n");
1118 }
1119 /* --------
1120 * Literals
1121 * --------
1122 */
1123 /* FIXME: [ seems to be ignored */
1124 else
1125 {
1126 if (*pFormat == '%' && header->type == FMT_TYPE_NUMBER)
1127 {
1128 /* Number formats: Percentage indicator, also a literal
1129 * Other formats: Literal
1130 * Doesn't type the format
1131 */
1132 num_header->flags |= FMT_FLAG_PERCENT;
1133 }
1134
1135 if (fmt_state & FMT_STATE_OPEN_COPY)
1136 {
1137 pOut[-1] = pOut[-1] + 1; /* Increase the length of the open copy */
1138 TRACE("extend copy (char '%c'), length now %d\n", *pFormat, pOut[-1]);
1139 }
1140 else
1141 {
1142 /* Create a new open copy */
1143 TRACE("New copy (char '%c')\n", *pFormat);
1144 NEED_SPACE(3 * sizeof(BYTE));
1145 *pOut++ = FMT_GEN_COPY;
1146 *pOut++ = pFormat - lpszFormat;
1147 *pOut++ = 0x1;
1148 fmt_state |= FMT_STATE_OPEN_COPY;
1149 }
1150 pFormat++;
1151 }
1152 }
1153
1154 *pOut++ = FMT_GEN_END;
1155
1156 header->size = pOut - rgbTok;
1157 if (pcbActual)
1158 *pcbActual = header->size;
1159
1160 return S_OK;
1161}
#define FMT_STATE_WROTE_DECIMAL
Definition: varformat.c:462
static const BYTE * VARIANT_GetNamedFormat(LPCWSTR lpszFormat)
Definition: varformat.c:443
struct tagFMT_HEADER FMT_HEADER
#define FMT_STATE_SEEN_HOURS
Definition: varformat.c:463
#define NEED_SPACE(x)
Definition: varformat.c:455
struct tagFMT_STRING_HEADER FMT_STRING_HEADER
#define FMT_FLAG_RTL
Definition: varformat.c:175
#define COULD_BE(typ)
Definition: varformat.c:458
#define FMT_STATE_WROTE_MINUTES
Definition: varformat.c:464
#define FMT_STATE_OPEN_COPY
Definition: varformat.c:461
GLuint start
Definition: gl.h:1545
_Check_return_ _CRTIMP int __cdecl wcsncmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#define memset(x, y, z)
Definition: compat.h:39

Referenced by test_VarFormatFromTokens(), and VarFormat().

◆ VarWeekdayName()

HRESULT WINAPI VarWeekdayName ( INT  iWeekday,
INT  fAbbrev,
INT  iFirstDay,
ULONG  dwFlags,
BSTR pbstrOut 
)

Definition at line 2568 of file varformat.c.

2570{
2571 DWORD localeValue;
2572 INT size;
2573
2574 /* Windows XP oleaut32.dll doesn't allow iWekday==0, contrary to MSDN */
2575 if (iWeekday < 1 || iWeekday > 7)
2576 return E_INVALIDARG;
2577 if (iFirstDay < 0 || iFirstDay > 7)
2578 return E_INVALIDARG;
2579 if (!pbstrOut)
2580 return E_INVALIDARG;
2581
2582 if (dwFlags)
2583 FIXME("Does not support dwFlags 0x%x, ignoring.\n", dwFlags);
2584
2585 /* If we have to use the default firstDay, find which one it is */
2586 if (iFirstDay == 0) {
2587 DWORD firstDay;
2588 localeValue = LOCALE_RETURN_NUMBER | LOCALE_IFIRSTDAYOFWEEK;
2590 (LPWSTR)&firstDay, sizeof(firstDay) / sizeof(WCHAR));
2591 if (!size) {
2592 ERR("GetLocaleInfo 0x%x failed.\n", localeValue);
2594 }
2595 iFirstDay = firstDay + 2;
2596 }
2597
2598 /* Determine what we need to return */
2599 localeValue = fAbbrev ? LOCALE_SABBREVDAYNAME1 : LOCALE_SDAYNAME1;
2600 localeValue += (7 + iWeekday - 1 + iFirstDay - 2) % 7;
2601
2602 /* Determine the size of the data, allocate memory and retrieve the data */
2603 size = GetLocaleInfoW(LOCALE_USER_DEFAULT, localeValue, NULL, 0);
2604 if (!size) {
2605 ERR("GetLocaleInfo 0x%x failed.\n", localeValue);
2607 }
2608 *pbstrOut = SysAllocStringLen(NULL, size - 1);
2609 if (!*pbstrOut)
2610 return E_OUTOFMEMORY;
2611 size = GetLocaleInfoW(LOCALE_USER_DEFAULT, localeValue, *pbstrOut, size);
2612 if (!size) {
2613 ERR("GetLocaleInfo 0x%x failed in 2nd stage?!\n", localeValue);
2614 SysFreeString(*pbstrOut);
2616 }
2617 return S_OK;
2618}

Referenced by Global_WeekdayName(), and test_VarWeekdayName().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( variant  )

Variable Documentation

◆ fmtCurrency

const BYTE fmtCurrency[0x26]
static
Initial value:

Definition at line 363 of file varformat.c.

◆ fmtFixed

const BYTE fmtFixed[0x11]
static
Initial value:
=
{
0x11,FMT_TYPE_NUMBER,sizeof(FMT_HEADER),0x0,0x0,0x0,
0x0,0x0,0x0,0x1,0x2,
}

Definition at line 378 of file varformat.c.

◆ fmtGeneralDate

const BYTE fmtGeneralDate[0x0a]
static
Initial value:
=
{
0x0,0x0,0x0,0x0,0x0,
}
struct tagFMT_SHORT_HEADER FMT_SHORT_HEADER

Definition at line 276 of file varformat.c.

Referenced by VarFormatDateTime().

◆ fmtGeneralNumber

const BYTE fmtGeneralNumber[sizeof(FMT_HEADER)]
static
Initial value:
=
{
sizeof(FMT_HEADER),FMT_TYPE_GENERAL,sizeof(FMT_HEADER),0x0,0x0,0x0
}

Definition at line 357 of file varformat.c.

◆ fmtLongDate

const BYTE fmtLongDate[0x0a]
static
Initial value:
=
{
0x0,0x0,0x0,0x0,0x0,
}

Definition at line 300 of file varformat.c.

Referenced by VarFormatDateTime().

◆ fmtLongTime

const BYTE fmtLongTime[0x0d]
static
Initial value:
=
{
0x0,0x0,0x0,0x0,0x0,
}

Definition at line 325 of file varformat.c.

Referenced by VarFormatDateTime().

◆ fmtMediumDate

const BYTE fmtMediumDate[0x0a]
static
Initial value:
=
{
0x0,0x0,0x0,0x0,0x0,
}

Definition at line 292 of file varformat.c.

◆ fmtMediumTime

const BYTE fmtMediumTime[0x11]
static
Initial value:

Definition at line 316 of file varformat.c.

◆ fmtOnOff

const BYTE fmtOnOff[0x0d]
static
Initial value:
=
{
0x0d,FMT_TYPE_NUMBER,sizeof(FMT_HEADER),0x0,0x0,0x0,
FMT_FLAG_BOOL,0x0,0x0,0x0,0x0,
}
#define FMT_FLAG_BOOL
Definition: varformat.c:193

Definition at line 349 of file varformat.c.

◆ fmtPercent

const BYTE fmtPercent[0x15]
static
Initial value:
=
{
0x15,FMT_TYPE_NUMBER,sizeof(FMT_HEADER),0x0,0x0,0x0,
FMT_FLAG_PERCENT,0x1,0x0,0x1,0x2,
}

Definition at line 394 of file varformat.c.

◆ fmtScientific

const BYTE fmtScientific[0x13]
static
Initial value:

Definition at line 403 of file varformat.c.

◆ fmtShortDate

const BYTE fmtShortDate[0x0a]
static
Initial value:
=
{
0x0,0x0,0x0,0x0,0x0,
}

Definition at line 284 of file varformat.c.

Referenced by VarFormatDateTime().

◆ fmtShortTime

const BYTE fmtShortTime[0x0c]
static
Initial value:

Definition at line 308 of file varformat.c.

Referenced by VarFormatDateTime().

◆ fmtStandard

const BYTE fmtStandard[0x11]
static
Initial value:

Definition at line 386 of file varformat.c.

◆ fmtTrueFalse

const BYTE fmtTrueFalse[0x0d]
static
Initial value:
=
{
0x0d,FMT_TYPE_NUMBER,sizeof(FMT_HEADER),0x0,0x0,0x0,
FMT_FLAG_BOOL,0x0,0x0,0x0,0x0,
}

Definition at line 333 of file varformat.c.

◆ fmtYesNo

const BYTE fmtYesNo[0x0d]
static
Initial value:
=
{
0x0d,FMT_TYPE_NUMBER,sizeof(FMT_HEADER),0x0,0x0,0x0,
FMT_FLAG_BOOL,0x0,0x0,0x0,0x0,
}

Definition at line 341 of file varformat.c.

◆ szCurrency

const WCHAR szCurrency[] = { 'C','u','r','r','e','n','c','y','\0' }
static

Definition at line 362 of file varformat.c.

◆ szFixed

const WCHAR szFixed[] = { 'F','i','x','e','d','\0' }
static

Definition at line 377 of file varformat.c.

◆ szGeneralDate

const WCHAR szGeneralDate[] = { 'G','e','n','e','r','a','l',' ','D','a','t','e','\0' }
static

Definition at line 275 of file varformat.c.

◆ szGeneralNumber

const WCHAR szGeneralNumber[] = { 'G','e','n','e','r','a','l',' ','N','u','m','b','e','r','\0' }
static

Definition at line 356 of file varformat.c.

◆ szLongDate

const WCHAR szLongDate[] = { 'L','o','n','g',' ','D','a','t','e','\0' }
static

Definition at line 299 of file varformat.c.

◆ szLongTime

const WCHAR szLongTime[] = { 'L','o','n','g',' ','T','i','m','e','\0' }
static

Definition at line 324 of file varformat.c.

◆ szMediumDate

const WCHAR szMediumDate[] = { 'M','e','d','i','u','m',' ','D','a','t','e','\0' }
static

Definition at line 291 of file varformat.c.

◆ szMediumTime

const WCHAR szMediumTime[] = { 'M','e','d','i','u','m',' ','T','i','m','e','\0' }
static

Definition at line 315 of file varformat.c.

◆ szOnOff

const WCHAR szOnOff[] = { 'O','n','/','O','f','f','\0' }
static

Definition at line 348 of file varformat.c.

◆ szPercent

const WCHAR szPercent[] = { 'P','e','r','c','e','n','t','\0' }
static

Definition at line 393 of file varformat.c.

Referenced by PagePrompt(), and VarFormatPercent().

◆ szPercent_d

const WCHAR szPercent_d[] = { '%','d','\0' }
static

Definition at line 47 of file varformat.c.

Referenced by VARIANT_FormatDate().

◆ szPercentZeroStar_d

const WCHAR szPercentZeroStar_d[] = { '%','0','*','d','\0' }
static

Definition at line 49 of file varformat.c.

Referenced by VARIANT_FormatNumber().

◆ szPercentZeroTwo_d

const WCHAR szPercentZeroTwo_d[] = { '%','0','2','d','\0' }
static

Definition at line 48 of file varformat.c.

Referenced by VARIANT_FormatDate().

◆ szScientific

const WCHAR szScientific[] = { 'S','c','i','e','n','t','i','f','i','c','\0' }
static

Definition at line 402 of file varformat.c.

◆ szShortDate

const WCHAR szShortDate[] = { 'S','h','o','r','t',' ','D','a','t','e','\0' }
static

Definition at line 283 of file varformat.c.

◆ szShortTime

const WCHAR szShortTime[] = { 'S','h','o','r','t',' ','T','i','m','e','\0' }
static

Definition at line 307 of file varformat.c.

◆ szStandard

const WCHAR szStandard[] = { 'S','t','a','n','d','a','r','d','\0' }
static

Definition at line 385 of file varformat.c.

◆ szTrueFalse

const WCHAR szTrueFalse[] = { 'T','r','u','e','/','F','a','l','s','e','\0' }
static

Definition at line 332 of file varformat.c.

◆ szYesNo

const WCHAR szYesNo[] = { 'Y','e','s','/','N','o','\0' }
static

Definition at line 340 of file varformat.c.

◆ VARIANT_NamedFormats

const NAMED_FORMAT VARIANT_NamedFormats[]
static
Initial value:
=
{
}
static const WCHAR szLongDate[]
Definition: varformat.c:299
static const WCHAR szScientific[]
Definition: varformat.c:402
static const BYTE fmtPercent[0x15]
Definition: varformat.c:394
static const BYTE fmtYesNo[0x0d]
Definition: varformat.c:341
static const WCHAR szOnOff[]
Definition: varformat.c:348
static const BYTE fmtGeneralNumber[sizeof(FMT_HEADER)]
Definition: varformat.c:357
static const BYTE fmtStandard[0x11]
Definition: varformat.c:386
static const WCHAR szShortTime[]
Definition: varformat.c:307
static const BYTE fmtCurrency[0x26]
Definition: varformat.c:363
static const WCHAR szFixed[]
Definition: varformat.c:377
static const BYTE fmtOnOff[0x0d]
Definition: varformat.c:349
static const WCHAR szCurrency[]
Definition: varformat.c:362
static const WCHAR szLongTime[]
Definition: varformat.c:324
static const WCHAR szShortDate[]
Definition: varformat.c:283
static const WCHAR szYesNo[]
Definition: varformat.c:340
static const BYTE fmtMediumTime[0x11]
Definition: varformat.c:316
static const BYTE fmtTrueFalse[0x0d]
Definition: varformat.c:333
static const BYTE fmtMediumDate[0x0a]
Definition: varformat.c:292
static const WCHAR szStandard[]
Definition: varformat.c:385
static const WCHAR szMediumTime[]
Definition: varformat.c:315
static const WCHAR szTrueFalse[]
Definition: varformat.c:332
static const WCHAR szGeneralNumber[]
Definition: varformat.c:356
static const BYTE fmtFixed[0x11]
Definition: varformat.c:378
static const BYTE fmtScientific[0x13]
Definition: varformat.c:403
static const WCHAR szMediumDate[]
Definition: varformat.c:291
static const WCHAR szGeneralDate[]
Definition: varformat.c:275

Definition at line 417 of file varformat.c.

Referenced by VARIANT_GetNamedFormat().