ReactOS 0.4.17-dev-573-g8315b8c
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 BYTE fmtGeneralDate [0x0a]
 
static const BYTE fmtShortDate [0x0a]
 
static const BYTE fmtMediumDate [0x0a]
 
static const BYTE fmtLongDate [0x0a]
 
static const BYTE fmtShortTime [0x0c]
 
static const BYTE fmtMediumTime [0x11]
 
static const BYTE fmtLongTime [0x0d]
 
static const BYTE fmtTrueFalse [0x0d]
 
static const BYTE fmtYesNo [0x0d]
 
static const BYTE fmtOnOff [0x0d]
 
static const BYTE fmtGeneralNumber [sizeof(FMT_HEADER)]
 
static const BYTE fmtCurrency [0x26]
 
static const BYTE fmtFixed [0x11]
 
static const BYTE fmtStandard [0x11]
 
static const BYTE fmtPercent [0x15]
 
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 438 of file varformat.c.

◆ FMT_DATE_A_LOWER

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

Definition at line 255 of file varformat.c.

◆ FMT_DATE_A_UPPER

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

Definition at line 252 of file varformat.c.

◆ FMT_DATE_AMPM_LOWER

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

Definition at line 254 of file varformat.c.

◆ FMT_DATE_AMPM_SYS1

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

Definition at line 250 of file varformat.c.

◆ FMT_DATE_AMPM_SYS2

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

Definition at line 253 of file varformat.c.

◆ FMT_DATE_AMPM_UPPER

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

Definition at line 251 of file varformat.c.

◆ FMT_DATE_DATE_SEP

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

Definition at line 219 of file varformat.c.

◆ FMT_DATE_DAY

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

Definition at line 223 of file varformat.c.

◆ FMT_DATE_DAY_0

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

Definition at line 224 of file varformat.c.

◆ FMT_DATE_DAY_LONG

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

Definition at line 226 of file varformat.c.

◆ FMT_DATE_DAY_SHORT

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

Definition at line 225 of file varformat.c.

◆ FMT_DATE_DAY_WEEK

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

Definition at line 230 of file varformat.c.

◆ FMT_DATE_GENERAL

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

Definition at line 220 of file varformat.c.

◆ FMT_DATE_HOUR

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

Definition at line 244 of file varformat.c.

◆ FMT_DATE_HOUR_0

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

Definition at line 245 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 246 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 247 of file varformat.c.

◆ FMT_DATE_LONG

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

Definition at line 228 of file varformat.c.

◆ FMT_DATE_MEDIUM

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

Definition at line 229 of file varformat.c.

◆ FMT_DATE_MIN

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

Definition at line 240 of file varformat.c.

◆ FMT_DATE_MIN_0

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

Definition at line 241 of file varformat.c.

◆ FMT_DATE_MON

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

Definition at line 232 of file varformat.c.

◆ FMT_DATE_MON_0

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

Definition at line 233 of file varformat.c.

◆ FMT_DATE_MON_LONG

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

Definition at line 235 of file varformat.c.

◆ FMT_DATE_MON_SHORT

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

Definition at line 234 of file varformat.c.

◆ FMT_DATE_QUARTER

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

Definition at line 221 of file varformat.c.

◆ FMT_DATE_SEC

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

Definition at line 242 of file varformat.c.

◆ FMT_DATE_SEC_0

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

Definition at line 243 of file varformat.c.

◆ FMT_DATE_SHORT

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

Definition at line 227 of file varformat.c.

◆ FMT_DATE_TIME_SEP

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

Definition at line 218 of file varformat.c.

◆ FMT_DATE_TIME_SYS

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

Definition at line 222 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 248 of file varformat.c.

◆ FMT_DATE_WEEK_YEAR

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

Definition at line 231 of file varformat.c.

◆ FMT_DATE_YEAR_0

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

Definition at line 237 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 236 of file varformat.c.

◆ FMT_DATE_YEAR_LONG

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

Definition at line 239 of file varformat.c.

◆ FMT_FLAG_BOOL

#define FMT_FLAG_BOOL   0x20 /* Boolean format */

Definition at line 189 of file varformat.c.

◆ FMT_FLAG_EXPONENT

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

Definition at line 187 of file varformat.c.

◆ FMT_FLAG_GT

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

Definition at line 170 of file varformat.c.

◆ FMT_FLAG_LT

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

Definition at line 169 of file varformat.c.

◆ FMT_FLAG_PERCENT

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

Definition at line 186 of file varformat.c.

◆ FMT_FLAG_RTL

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

Definition at line 171 of file varformat.c.

◆ FMT_FLAG_THOUSANDS

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

Definition at line 188 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 215 of file varformat.c.

◆ FMT_GEN_END

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

Definition at line 217 of file varformat.c.

◆ FMT_GEN_INLINE

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

Definition at line 216 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 257 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 256 of file varformat.c.

◆ FMT_NUM_CURRENCY

#define FMT_NUM_CURRENCY   0x3B /* Currency symbol */

Definition at line 263 of file varformat.c.

◆ FMT_NUM_DECIMAL

#define FMT_NUM_DECIMAL   0x36 /* Decimal separator */

Definition at line 258 of file varformat.c.

◆ FMT_NUM_EXP_NEG_L

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

Definition at line 262 of file varformat.c.

◆ FMT_NUM_EXP_NEG_U

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

Definition at line 260 of file varformat.c.

◆ FMT_NUM_EXP_POS_L

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

Definition at line 261 of file varformat.c.

◆ FMT_NUM_EXP_POS_U

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

Definition at line 259 of file varformat.c.

◆ FMT_NUM_ON_OFF

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

Definition at line 266 of file varformat.c.

◆ FMT_NUM_TRUE_FALSE

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

Definition at line 264 of file varformat.c.

◆ FMT_NUM_YES_NO

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

Definition at line 265 of file varformat.c.

◆ FMT_STATE_OPEN_COPY

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

Definition at line 441 of file varformat.c.

◆ FMT_STATE_SEEN_HOURS

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

Definition at line 443 of file varformat.c.

◆ FMT_STATE_WROTE_DECIMAL

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

Definition at line 442 of file varformat.c.

◆ FMT_STATE_WROTE_MINUTES

#define FMT_STATE_WROTE_MINUTES   0x8 /* Wrote minutes */

Definition at line 444 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 268 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 267 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 144 of file varformat.c.

◆ FMT_TYPE_DATE

#define FMT_TYPE_DATE   0x3

Definition at line 141 of file varformat.c.

◆ FMT_TYPE_GENERAL

#define FMT_TYPE_GENERAL   0x1

Definition at line 139 of file varformat.c.

◆ FMT_TYPE_NUMBER

#define FMT_TYPE_NUMBER   0x2

Definition at line 140 of file varformat.c.

◆ FMT_TYPE_STRING

#define FMT_TYPE_STRING   0x4

Definition at line 142 of file varformat.c.

◆ FMT_TYPE_UNKNOWN

#define FMT_TYPE_UNKNOWN   0x0

Definition at line 138 of file varformat.c.

◆ FmtGetNegative

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

Definition at line 161 of file varformat.c.

◆ FmtGetNull

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

Definition at line 163 of file varformat.c.

◆ FmtGetPositive

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

Definition at line 160 of file varformat.c.

◆ FmtGetZero

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

Definition at line 162 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:1675
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define LOCALE_USER_DEFAULT
short WCHAR
Definition: pedump.c:58
uint16_t * LPWSTR
Definition: typedefs.h:56

Definition at line 2218 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 435 of file varformat.c.

◆ NUM_WRITE_ON

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

Definition at line 1145 of file varformat.c.

◆ NUM_WROTE_DEC

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

Definition at line 1144 of file varformat.c.

◆ NUM_WROTE_SIGN

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

Definition at line 1146 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:43
#define VTBIT_BOOL
Definition: variant.h:37
#define VTBIT_UINT
Definition: variant.h:45

Definition at line 2048 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 416 of file varformat.c.

◆ NAMED_FORMAT

Function Documentation

◆ FormatCompareFn()

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

Definition at line 418 of file varformat.c.

419{
421}
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 2144 of file varformat.c.

2147{
2148 BYTE buff[256];
2149 HRESULT hres;
2150
2151 TRACE("%s, %s, %d, %d, %#lx, %p.\n", debugstr_variant(pVarIn), debugstr_w(lpszFormat),
2152 nFirstDay, nFirstWeek, dwFlags, pbstrOut);
2153
2154 if (!pbstrOut)
2155 return E_INVALIDARG;
2156 *pbstrOut = NULL;
2157
2158 hres = VarTokenizeFormatString(lpszFormat, buff, sizeof(buff), nFirstDay,
2159 nFirstWeek, LOCALE_USER_DEFAULT, NULL);
2160 if (SUCCEEDED(hres))
2161 hres = VarFormatFromTokens(pVarIn, lpszFormat, buff, dwFlags,
2162 pbstrOut, LOCALE_USER_DEFAULT);
2163 TRACE("returning %#lx, %s\n", hres, debugstr_w(*pbstrOut));
2164 return hres;
2165}
#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:475
HRESULT WINAPI VarFormatFromTokens(LPVARIANT pVarIn, LPOLESTR lpszFormat, LPBYTE rgbTok, ULONG dwFlags, BSTR *pbstrOut, LCID lcid)
Definition: varformat.c:2056
static const char * debugstr_variant(const VARIANT *var)
Definition: dom.c:505
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define debugstr_w
Definition: kernel32.h:32
HRESULT hres
Definition: protocol.c:465
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
static const char *static const char const char DWORD void DWORD *static const char const char DWORD void DWORD *static const char DWORD DWORD void * buff
Definition: shcore.c:41
#define TRACE(s)
Definition: solgame.cpp:4
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 2424 of file varformat.c.

2427{
2428 HRESULT hRet;
2429 VARIANT vStr;
2430 CY cy;
2431
2432 TRACE("%s, %d, %d, %d, %d, %#lx, %p.\n", debugstr_variant(pVarIn), nDigits, nLeading,
2433 nParens, nGrouping, dwFlags, pbstrOut);
2434
2435 if (!pVarIn || !pbstrOut || nDigits > 9)
2436 return E_INVALIDARG;
2437
2438 *pbstrOut = NULL;
2439
2440 if (V_VT(pVarIn) == VT_BSTR || V_VT(pVarIn) == (VT_BSTR | VT_BYREF))
2441 {
2442 hRet = VarCyFromStr(V_ISBYREF(pVarIn) ? *V_BSTRREF(pVarIn) : V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &cy);
2443 if (FAILED(hRet)) return hRet;
2444 V_VT(&vStr) = VT_CY;
2445 V_CY(&vStr) = cy;
2446 }
2447 else
2448 {
2449 V_VT(&vStr) = VT_EMPTY;
2450 hRet = VariantCopyInd(&vStr, pVarIn);
2451 }
2452
2453 if (SUCCEEDED(hRet))
2454 hRet = VariantChangeTypeEx(&vStr, &vStr, LOCALE_USER_DEFAULT, 0, VT_BSTR);
2455
2456 if (SUCCEEDED(hRet))
2457 {
2458 WCHAR buff[256], decimal[8], thousands[4], currency[13];
2459 CURRENCYFMTW numfmt;
2460
2461 if (nDigits < 0)
2462 GETLOCALENUMBER(LOCALE_IDIGITS, NumDigits);
2463 else
2464 numfmt.NumDigits = nDigits;
2465
2466 if (nLeading == -2)
2467 GETLOCALENUMBER(LOCALE_ILZERO, LeadingZero);
2468 else if (nLeading == -1)
2469 numfmt.LeadingZero = 1;
2470 else
2471 numfmt.LeadingZero = 0;
2472
2473 if (nGrouping == -2)
2474 {
2475 WCHAR grouping[10];
2476 grouping[2] = '\0';
2478 numfmt.Grouping = grouping[2] == '2' ? 32 : grouping[0] - '0';
2479 }
2480 else if (nGrouping == -1)
2481 numfmt.Grouping = 3; /* 3 = "n,nnn.nn" */
2482 else
2483 numfmt.Grouping = 0; /* 0 = No grouping */
2484
2485 if (nParens == -2)
2486 GETLOCALENUMBER(LOCALE_INEGCURR, NegativeOrder);
2487 else if (nParens == -1)
2488 numfmt.NegativeOrder = 0; /* 0 = "(xxx)" */
2489 else
2490 numfmt.NegativeOrder = 1; /* 1 = "-xxx" */
2491
2492 GETLOCALENUMBER(LOCALE_ICURRENCY, PositiveOrder);
2493
2494 numfmt.lpDecimalSep = decimal;
2496 numfmt.lpThousandSep = thousands;
2498 numfmt.lpCurrencySymbol = currency;
2500
2501 /* use NLS as per VarFormatNumber() */
2503 {
2504 *pbstrOut = SysAllocString(buff);
2505 if (!*pbstrOut)
2506 hRet = E_OUTOFMEMORY;
2507 }
2508 else
2509 hRet = DISP_E_TYPEMISMATCH;
2510
2511 SysFreeString(V_BSTR(&vStr));
2512 }
2513 return hRet;
2514}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
@ VT_BSTR
Definition: compat.h:2303
@ VT_BYREF
Definition: compat.h:2342
@ VT_CY
Definition: compat.h:2301
@ VT_EMPTY
Definition: compat.h:2295
#define GETLOCALENUMBER(type, field)
Definition: varformat.c:2218
HRESULT WINAPI VarCyFromStr(const OLECHAR *strIn, LCID lcid, ULONG dwFlags, CY *pCyOut)
Definition: vartype.c:3569
#define FAILED(hr)
Definition: intsafe.h:51
INT WINAPI GetCurrencyFormatW(LCID lcid, DWORD dwFlags, LPCWSTR lpszValue, const CURRENCYFMTW *lpFormat, LPWSTR lpCurrencyStr, int cchOut)
Definition: lcformat.c:1401
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:240
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:273
#define V_BSTRREF(A)
Definition: oleauto.h:227
#define V_ISBYREF(A)
Definition: oleauto.h:217
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_CY(A)
Definition: oleauto.h:229
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:586
UINT LeadingZero
Definition: winnls.h:693
LPWSTR lpDecimalSep
Definition: winnls.h:695
UINT NumDigits
Definition: winnls.h:692
LPWSTR lpCurrencySymbol
Definition: winnls.h:699
UINT Grouping
Definition: winnls.h:694
UINT NegativeOrder
Definition: winnls.h:697
LPWSTR lpThousandSep
Definition: winnls.h:696
Definition: compat.h:2255
HRESULT WINAPI VariantChangeTypeEx(VARIANTARG *pvargDest, const VARIANTARG *pvargSrc, LCID lcid, USHORT wFlags, VARTYPE vt)
Definition: variant.c:965
HRESULT WINAPI VariantCopyInd(VARIANT *pvargDest, const VARIANTARG *pvargSrc)
Definition: variant.c:823
#define DISP_E_TYPEMISMATCH
Definition: winerror.h:3617
#define LOCALE_SGROUPING
Definition: winnls.h:54
#define LOCALE_SDECIMAL
Definition: winnls.h:52
#define LOCALE_ICURRENCY
Definition: winnls.h:66
#define LOCALE_IDIGITS
Definition: winnls.h:55
#define LOCALE_STHOUSAND
Definition: winnls.h:53
#define LOCALE_ILZERO
Definition: winnls.h:56
#define LOCALE_SCURRENCY
Definition: winnls.h:59
#define LOCALE_INEGCURR
Definition: winnls.h:67

Referenced by Global_FormatCurrency(), and test_VarFormatCurrency().

◆ VarFormatDateTime()

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

Definition at line 2196 of file varformat.c.

2197{
2198 static WCHAR szEmpty[] = L"";
2199 const BYTE* lpFmt = NULL;
2200
2201 TRACE("%s, %d, %#lx, %p.\n", debugstr_variant(pVarIn), nFormat, dwFlags, pbstrOut);
2202
2203 if (!pVarIn || !pbstrOut || nFormat < 0 || nFormat > 4)
2204 return E_INVALIDARG;
2205
2206 switch (nFormat)
2207 {
2208 case 0: lpFmt = fmtGeneralDate; break;
2209 case 1: lpFmt = fmtLongDate; break;
2210 case 2: lpFmt = fmtShortDate; break;
2211 case 3: lpFmt = fmtLongTime; break;
2212 case 4: lpFmt = fmtShortTime; break;
2213 }
2214 return VarFormatFromTokens(pVarIn, szEmpty, (BYTE*)lpFmt, dwFlags,
2215 pbstrOut, LOCALE_USER_DEFAULT);
2216}
static const WCHAR szEmpty[]
Definition: provider.c:50
static const BYTE fmtLongDate[0x0a]
Definition: varformat.c:292
static const BYTE fmtGeneralDate[0x0a]
Definition: varformat.c:271
static const BYTE fmtShortTime[0x0c]
Definition: varformat.c:299
static const BYTE fmtShortDate[0x0a]
Definition: varformat.c:278
static const BYTE fmtLongTime[0x0d]
Definition: varformat.c:314
#define L(x)
Definition: resources.c:13

Referenced by Global_FormatDateTime(), and test_VarFormatDateTime().

◆ VarFormatFromTokens()

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

Definition at line 2056 of file varformat.c.

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

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 2247 of file varformat.c.

2249{
2250 HRESULT hRet;
2251 VARIANT vStr;
2252
2253 TRACE("%s, %d, %d, %d, %d, %#lx, %p.\n", debugstr_variant(pVarIn), nDigits, nLeading,
2254 nParens, nGrouping, dwFlags, pbstrOut);
2255
2256 if (!pVarIn || !pbstrOut || nDigits > 9)
2257 return E_INVALIDARG;
2258
2259 *pbstrOut = NULL;
2260
2261 V_VT(&vStr) = VT_EMPTY;
2262 hRet = VariantCopyInd(&vStr, pVarIn);
2263
2264 if (SUCCEEDED(hRet))
2265 hRet = VariantChangeTypeEx(&vStr, &vStr, LCID_US, 0, VT_BSTR);
2266
2267 if (SUCCEEDED(hRet))
2268 {
2269 WCHAR buff[256], decimal[8], thousands[8];
2270 NUMBERFMTW numfmt;
2271
2272 /* Although MSDN makes it clear that the native versions of these functions
2273 * are implemented using VarTokenizeFormatString()/VarFormatFromTokens(),
2274 * using NLS gives us the same result.
2275 */
2276 if (nDigits < 0)
2277 GETLOCALENUMBER(LOCALE_IDIGITS, NumDigits);
2278 else
2279 numfmt.NumDigits = nDigits;
2280
2281 if (nLeading == -2)
2282 GETLOCALENUMBER(LOCALE_ILZERO, LeadingZero);
2283 else if (nLeading == -1)
2284 numfmt.LeadingZero = 1;
2285 else
2286 numfmt.LeadingZero = 0;
2287
2288 if (nGrouping == -2)
2289 {
2290 WCHAR grouping[10];
2291 grouping[2] = '\0';
2293 numfmt.Grouping = grouping[2] == '2' ? 32 : grouping[0] - '0';
2294 }
2295 else if (nGrouping == -1)
2296 numfmt.Grouping = 3; /* 3 = "n,nnn.nn" */
2297 else
2298 numfmt.Grouping = 0; /* 0 = No grouping */
2299
2300 if (nParens == -2)
2301 GETLOCALENUMBER(LOCALE_INEGNUMBER, NegativeOrder);
2302 else if (nParens == -1)
2303 numfmt.NegativeOrder = 0; /* 0 = "(xxx)" */
2304 else
2305 numfmt.NegativeOrder = 1; /* 1 = "-xxx" */
2306
2307 numfmt.lpDecimalSep = decimal;
2309 numfmt.lpThousandSep = thousands;
2311
2312 if (GetNumberFormatW(LOCALE_USER_DEFAULT, 0, V_BSTR(&vStr), &numfmt, buff, ARRAY_SIZE(buff)))
2313 {
2314 *pbstrOut = SysAllocString(buff);
2315 if (!*pbstrOut)
2316 hRet = E_OUTOFMEMORY;
2317 }
2318 else
2319 hRet = DISP_E_TYPEMISMATCH;
2320
2321 SysFreeString(V_BSTR(&vStr));
2322 }
2323 return hRet;
2324}
#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:1130
UINT NumDigits
Definition: winnls.h:726
LPWSTR lpDecimalSep
Definition: winnls.h:729
UINT Grouping
Definition: winnls.h:728
UINT NegativeOrder
Definition: winnls.h:731
LPWSTR lpThousandSep
Definition: winnls.h:730
UINT LeadingZero
Definition: winnls.h:727
#define LOCALE_INEGNUMBER
Definition: winnls.h:57

Referenced by Global_FormatNumber(), 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 2351 of file varformat.c.

2353{
2354 WCHAR buff[256];
2355 HRESULT hRet;
2356 VARIANT vDbl;
2357
2358 TRACE("%s, %d, %d, %d, %d, %#lx, %p.\n", debugstr_variant(pVarIn), nDigits, nLeading,
2359 nParens, nGrouping, dwFlags, pbstrOut);
2360
2361 if (!pVarIn || !pbstrOut || nDigits > 9)
2362 return E_INVALIDARG;
2363
2364 *pbstrOut = NULL;
2365
2366 V_VT(&vDbl) = VT_EMPTY;
2367 hRet = VariantCopyInd(&vDbl, pVarIn);
2368
2369 if (SUCCEEDED(hRet))
2370 {
2371 hRet = VariantChangeTypeEx(&vDbl, &vDbl, LOCALE_USER_DEFAULT, 0, VT_R8);
2372
2373 if (SUCCEEDED(hRet))
2374 {
2375 if (V_R8(&vDbl) > (R8_MAX / 100.0))
2376 return DISP_E_OVERFLOW;
2377
2378 V_R8(&vDbl) *= 100.0;
2379 hRet = VarFormatNumber(&vDbl, nDigits, nLeading, nParens,
2380 nGrouping, dwFlags, pbstrOut);
2381
2382 if (SUCCEEDED(hRet))
2383 {
2384 DWORD dwLen = lstrlenW(*pbstrOut);
2385 BOOL bBracket = (*pbstrOut)[dwLen] == ')';
2386
2387 dwLen -= bBracket;
2388 memcpy(buff, *pbstrOut, dwLen * sizeof(WCHAR));
2389 lstrcpyW(buff + dwLen, bBracket ? L"%)" : L"%");
2390 SysFreeString(*pbstrOut);
2391 *pbstrOut = SysAllocString(buff);
2392 if (!*pbstrOut)
2393 hRet = E_OUTOFMEMORY;
2394 }
2395 }
2396 }
2397 return hRet;
2398}
#define lstrcpyW
Definition: compat.h:749
@ VT_R8
Definition: compat.h:2300
#define lstrlenW
Definition: compat.h:750
HRESULT WINAPI VarFormatNumber(LPVARIANT pVarIn, INT nDigits, INT nLeading, INT nParens, INT nGrouping, ULONG dwFlags, BSTR *pbstrOut)
Definition: varformat.c:2247
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:71

Referenced by Global_FormatPercent().

◆ VARIANT_FormatDate()

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

Definition at line 1561 of file varformat.c.

1564{
1565 WCHAR buff[256], *pBuff = buff;
1566 VARIANT vDate;
1567 UDATE udate;
1568 FMT_HEADER *header = (FMT_HEADER*)rgbTok;
1569 FMT_DATE_HEADER *dateHeader;
1570 const BYTE* pToken = NULL;
1571 HRESULT hRes;
1572
1573 TRACE("%s, %s, %p, %#lx, %p, %#lx.\n", debugstr_variant(pVarIn),
1574 debugstr_w(lpszFormat), rgbTok, dwFlags, pbstrOut, lcid);
1575
1576 V_VT(&vDate) = VT_EMPTY;
1577
1578 if (V_TYPE(pVarIn) == VT_EMPTY || V_TYPE(pVarIn) == VT_NULL)
1579 {
1580 dateHeader = (FMT_DATE_HEADER*)(rgbTok + FmtGetNegative(header));
1581 V_DATE(&vDate) = 0;
1582 }
1583 else
1584 {
1586
1587 hRes = VariantChangeTypeEx(&vDate, pVarIn, lcid, usFlags, VT_DATE);
1588 /* 31809.40 and similar are treated as invalid by coercion functions but
1589 * it simply is a DATE in string form as far as VarFormat is concerned
1590 */
1591 if (FAILED(hRes))
1592 {
1593 if (V_TYPE(pVarIn) == VT_BSTR)
1594 {
1595 DATE out;
1596 OLECHAR *endptr = NULL;
1597 /* Try consume the string with wcstod */
1598 double tmp = wcstod(V_BSTR(pVarIn), &endptr);
1599
1600 /* Not a double in string form */
1601 if (*endptr)
1602 return hRes;
1603
1604 hRes = VarDateFromR8(tmp, &out);
1605
1606 if (FAILED(hRes))
1607 return hRes;
1608
1609 V_VT(&vDate) = VT_DATE;
1610 V_DATE(&vDate) = out;
1611 }
1612 else
1613 return hRes;
1614 }
1615
1616 dateHeader = (FMT_DATE_HEADER*)(rgbTok + FmtGetPositive(header));
1617 }
1618
1619 hRes = VarUdateFromDate(V_DATE(&vDate), 0 /* FIXME: flags? */, &udate);
1620 if (FAILED(hRes))
1621 return hRes;
1622 pToken = (const BYTE*)dateHeader + sizeof(FMT_DATE_HEADER);
1623
1624 while (*pToken != FMT_GEN_END)
1625 {
1626 DWORD dwVal = 0, localeValue = 0, dwFmt = 0;
1627 LPCWSTR szPrintFmt = NULL;
1628 WCHAR defaultChar = '?';
1629
1630 if (pToken - rgbTok > header->size)
1631 {
1632 ERR("Ran off the end of the format!\n");
1633 hRes = E_INVALIDARG;
1634 goto VARIANT_FormatDate_Exit;
1635 }
1636
1637 switch (*pToken)
1638 {
1639 case FMT_GEN_COPY:
1640 TRACE("copy %s\n", debugstr_wn(lpszFormat + pToken[1], pToken[2]));
1641 memcpy(pBuff, lpszFormat + pToken[1], pToken[2] * sizeof(WCHAR));
1642 pBuff += pToken[2];
1643 pToken += 2;
1644 break;
1645
1646 case FMT_GEN_INLINE:
1647 pToken += 2;
1648 TRACE("copy %s\n", debugstr_a((LPCSTR)pToken));
1649 while (*pToken)
1650 *pBuff++ = *pToken++;
1651 break;
1652
1653 case FMT_DATE_TIME_SEP:
1654 TRACE("time separator\n");
1655 localeValue = LOCALE_STIME;
1656 defaultChar = ':';
1657 break;
1658
1659 case FMT_DATE_DATE_SEP:
1660 TRACE("date separator\n");
1661 localeValue = LOCALE_SDATE;
1662 defaultChar = '/';
1663 break;
1664
1665 case FMT_DATE_GENERAL:
1666 {
1667 BSTR date = NULL;
1668 WCHAR *pDate;
1669 hRes = VarBstrFromDate(V_DATE(&vDate), lcid, 0, &date);
1670 if (FAILED(hRes))
1671 goto VARIANT_FormatDate_Exit;
1672 pDate = date;
1673 while (*pDate)
1674 *pBuff++ = *pDate++;
1676 }
1677 break;
1678
1679 case FMT_DATE_QUARTER:
1680 if (udate.st.wMonth <= 3)
1681 *pBuff++ = '1';
1682 else if (udate.st.wMonth <= 6)
1683 *pBuff++ = '2';
1684 else if (udate.st.wMonth <= 9)
1685 *pBuff++ = '3';
1686 else
1687 *pBuff++ = '4';
1688 break;
1689
1690 case FMT_DATE_TIME_SYS:
1691 {
1692 /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
1693 BSTR date = NULL;
1694 WCHAR *pDate;
1695 hRes = VarBstrFromDate(V_DATE(&vDate), lcid, VAR_TIMEVALUEONLY, &date);
1696 if (FAILED(hRes))
1697 goto VARIANT_FormatDate_Exit;
1698 pDate = date;
1699 while (*pDate)
1700 *pBuff++ = *pDate++;
1702 }
1703 break;
1704
1705 case FMT_DATE_DAY:
1706 szPrintFmt = L"%d";
1707 dwVal = udate.st.wDay;
1708 break;
1709
1710 case FMT_DATE_DAY_0:
1711 szPrintFmt = L"%02d";
1712 dwVal = udate.st.wDay;
1713 break;
1714
1715 case FMT_DATE_DAY_SHORT:
1716 /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
1717 TRACE("short day\n");
1718 localeValue = LOCALE_SABBREVDAYNAME1 + (udate.st.wDayOfWeek + 6)%7;
1719 defaultChar = '?';
1720 break;
1721
1722 case FMT_DATE_DAY_LONG:
1723 /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
1724 TRACE("long day\n");
1725 localeValue = LOCALE_SDAYNAME1 + (udate.st.wDayOfWeek + 6)%7;
1726 defaultChar = '?';
1727 break;
1728
1729 case FMT_DATE_SHORT:
1730 /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
1731 dwFmt = LOCALE_SSHORTDATE;
1732 break;
1733
1734 case FMT_DATE_LONG:
1735 /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
1736 dwFmt = LOCALE_SLONGDATE;
1737 break;
1738
1739 case FMT_DATE_MEDIUM:
1740 FIXME("Medium date treated as long date\n");
1741 dwFmt = LOCALE_SLONGDATE;
1742 break;
1743
1744 case FMT_DATE_DAY_WEEK:
1745 szPrintFmt = L"%d";
1746 if (pToken[1])
1747 dwVal = udate.st.wDayOfWeek + 2 - pToken[1];
1748 else
1749 {
1750 GetLocaleInfoW(lcid,LOCALE_RETURN_NUMBER|LOCALE_IFIRSTDAYOFWEEK,
1751 (LPWSTR)&dwVal, sizeof(dwVal)/sizeof(WCHAR));
1752 dwVal = udate.st.wDayOfWeek + 1 - dwVal;
1753 }
1754 pToken++;
1755 break;
1756
1757 case FMT_DATE_WEEK_YEAR:
1758 szPrintFmt = L"%d";
1759 dwVal = udate.wDayOfYear / 7 + 1;
1760 pToken += 2;
1761 FIXME("Ignoring nFirstDay of %d, nFirstWeek of %d\n", pToken[0], pToken[1]);
1762 break;
1763
1764 case FMT_DATE_MON:
1765 szPrintFmt = L"%d";
1766 dwVal = udate.st.wMonth;
1767 break;
1768
1769 case FMT_DATE_MON_0:
1770 szPrintFmt = L"%02d";
1771 dwVal = udate.st.wMonth;
1772 break;
1773
1774 case FMT_DATE_MON_SHORT:
1775 /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
1776 TRACE("short month\n");
1777 localeValue = LOCALE_SABBREVMONTHNAME1 + udate.st.wMonth - 1;
1778 defaultChar = '?';
1779 break;
1780
1781 case FMT_DATE_MON_LONG:
1782 /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */
1783 TRACE("long month\n");
1784 localeValue = LOCALE_SMONTHNAME1 + udate.st.wMonth - 1;
1785 defaultChar = '?';
1786 break;
1787
1788 case FMT_DATE_YEAR_DOY:
1789 szPrintFmt = L"%d";
1790 dwVal = udate.wDayOfYear;
1791 break;
1792
1793 case FMT_DATE_YEAR_0:
1794 szPrintFmt = L"%02d";
1795 dwVal = udate.st.wYear % 100;
1796 break;
1797
1798 case FMT_DATE_YEAR_LONG:
1799 szPrintFmt = L"%d";
1800 dwVal = udate.st.wYear;
1801 break;
1802
1803 case FMT_DATE_MIN:
1804 szPrintFmt = L"%d";
1805 dwVal = udate.st.wMinute;
1806 break;
1807
1808 case FMT_DATE_MIN_0:
1809 szPrintFmt = L"%02d";
1810 dwVal = udate.st.wMinute;
1811 break;
1812
1813 case FMT_DATE_SEC:
1814 szPrintFmt = L"%d";
1815 dwVal = udate.st.wSecond;
1816 break;
1817
1818 case FMT_DATE_SEC_0:
1819 szPrintFmt = L"%02d";
1820 dwVal = udate.st.wSecond;
1821 break;
1822
1823 case FMT_DATE_HOUR:
1824 szPrintFmt = L"%d";
1825 dwVal = udate.st.wHour;
1826 break;
1827
1828 case FMT_DATE_HOUR_0:
1829 case FMT_DATE_TIME_UNK2:
1830 szPrintFmt = L"%02d";
1831 dwVal = udate.st.wHour;
1832 break;
1833
1834 case FMT_DATE_HOUR_12:
1835 szPrintFmt = L"%d";
1836 dwVal = udate.st.wHour ? udate.st.wHour > 12 ? udate.st.wHour - 12 : udate.st.wHour : 12;
1837 break;
1838
1839 case FMT_DATE_HOUR_12_0:
1840 szPrintFmt = L"%02d";
1841 dwVal = udate.st.wHour ? udate.st.wHour > 12 ? udate.st.wHour - 12 : udate.st.wHour : 12;
1842 break;
1843
1844 case FMT_DATE_AMPM_SYS1:
1845 case FMT_DATE_AMPM_SYS2:
1846 localeValue = udate.st.wHour < 12 ? LOCALE_S1159 : LOCALE_S2359;
1847 defaultChar = '?';
1848 break;
1849
1851 *pBuff++ = udate.st.wHour < 12 ? 'A' : 'P';
1852 *pBuff++ = 'M';
1853 break;
1854
1855 case FMT_DATE_A_UPPER:
1856 *pBuff++ = udate.st.wHour < 12 ? 'A' : 'P';
1857 break;
1858
1860 *pBuff++ = udate.st.wHour < 12 ? 'a' : 'p';
1861 *pBuff++ = 'm';
1862 break;
1863
1864 case FMT_DATE_A_LOWER:
1865 *pBuff++ = udate.st.wHour < 12 ? 'a' : 'p';
1866 break;
1867
1868 default:
1869 ERR("Unknown token 0x%02x!\n", *pToken);
1870 hRes = E_INVALIDARG;
1871 goto VARIANT_FormatDate_Exit;
1872 }
1873 if (localeValue)
1874 {
1875 *pBuff = '\0';
1876 if (GetLocaleInfoW(lcid, localeValue, pBuff, ARRAY_SIZE(buff)-(pBuff-buff)))
1877 {
1878 TRACE("added %s\n", debugstr_w(pBuff));
1879 while (*pBuff)
1880 pBuff++;
1881 }
1882 else
1883 {
1884 TRACE("added %d %c\n", defaultChar, defaultChar);
1885 *pBuff++ = defaultChar;
1886 }
1887 }
1888 else if (dwFmt)
1889 {
1890 WCHAR fmt_buff[80];
1891
1892 if (!GetLocaleInfoW(lcid, dwFmt, fmt_buff, ARRAY_SIZE(fmt_buff)) ||
1893 !get_date_format(lcid, 0, &udate.st, fmt_buff, pBuff, ARRAY_SIZE(buff)-(pBuff-buff)))
1894 {
1895 hRes = E_INVALIDARG;
1896 goto VARIANT_FormatDate_Exit;
1897 }
1898 while (*pBuff)
1899 pBuff++;
1900 }
1901 else if (szPrintFmt)
1902 {
1903 swprintf(pBuff, ARRAY_SIZE(buff) - (pBuff - buff), szPrintFmt, dwVal);
1904 while (*pBuff)
1905 pBuff++;
1906 }
1907 pToken++;
1908 }
1909
1910VARIANT_FormatDate_Exit:
1911 *pBuff = '\0';
1912 TRACE("buff is %s\n", debugstr_w(buff));
1913 if (SUCCEEDED(hRes))
1914 {
1915 *pbstrOut = SysAllocString(buff);
1916 if (!*pbstrOut)
1917 hRes = E_OUTOFMEMORY;
1918 }
1919 return hRes;
1920}
#define FIXME(fmt,...)
Definition: precomp.h:53
double DATE
Definition: compat.h:2253
WCHAR OLECHAR
Definition: compat.h:2292
OLECHAR * BSTR
Definition: compat.h:2293
static int get_date_format(const NLS_LOCALE_DATA *locale, DWORD flags, const SYSTEMTIME *systime, const WCHAR *format, WCHAR *buffer, int len)
Definition: locale.c:7930
_ACRTIMP double __cdecl wcstod(const wchar_t *, wchar_t **)
Definition: wcs.c:802
#define FMT_DATE_DAY
Definition: varformat.c:223
#define FmtGetPositive(x)
Definition: varformat.c:160
#define FMT_DATE_HOUR
Definition: varformat.c:244
#define FMT_DATE_MON_SHORT
Definition: varformat.c:234
#define FMT_DATE_SHORT
Definition: varformat.c:227
#define FMT_DATE_A_LOWER
Definition: varformat.c:255
#define FMT_DATE_MON_0
Definition: varformat.c:233
#define FMT_DATE_AMPM_UPPER
Definition: varformat.c:251
#define FMT_DATE_YEAR_LONG
Definition: varformat.c:239
#define FMT_DATE_HOUR_12
Definition: varformat.c:246
#define FMT_DATE_SEC
Definition: varformat.c:242
#define FMT_DATE_HOUR_12_0
Definition: varformat.c:247
#define FMT_DATE_MON_LONG
Definition: varformat.c:235
#define FMT_DATE_DAY_0
Definition: varformat.c:224
#define FmtGetNegative(x)
Definition: varformat.c:161
#define FMT_DATE_DAY_SHORT
Definition: varformat.c:225
#define FMT_DATE_TIME_SYS
Definition: varformat.c:222
#define FMT_DATE_TIME_SEP
Definition: varformat.c:218
#define FMT_DATE_MEDIUM
Definition: varformat.c:229
#define FMT_GEN_COPY
Definition: varformat.c:215
#define FMT_GEN_END
Definition: varformat.c:217
#define FMT_DATE_YEAR_DOY
Definition: varformat.c:236
#define FMT_DATE_MON
Definition: varformat.c:232
#define FMT_DATE_TIME_UNK2
Definition: varformat.c:248
#define FMT_DATE_WEEK_YEAR
Definition: varformat.c:231
#define FMT_DATE_QUARTER
Definition: varformat.c:221
#define FMT_DATE_MIN_0
Definition: varformat.c:241
#define FMT_DATE_HOUR_0
Definition: varformat.c:245
#define FMT_DATE_DAY_WEEK
Definition: varformat.c:230
#define FMT_DATE_AMPM_LOWER
Definition: varformat.c:254
#define FMT_DATE_DAY_LONG
Definition: varformat.c:226
#define FMT_DATE_LONG
Definition: varformat.c:228
#define FMT_DATE_GENERAL
Definition: varformat.c:220
#define FMT_DATE_A_UPPER
Definition: varformat.c:252
#define FMT_DATE_DATE_SEP
Definition: varformat.c:219
#define FMT_DATE_AMPM_SYS1
Definition: varformat.c:250
#define FMT_DATE_AMPM_SYS2
Definition: varformat.c:253
#define FMT_DATE_YEAR_0
Definition: varformat.c:237
#define FMT_DATE_SEC_0
Definition: varformat.c:243
#define FMT_GEN_INLINE
Definition: varformat.c:216
#define FMT_DATE_MIN
Definition: varformat.c:240
HRESULT WINAPI VarBstrFromDate(DATE dateIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
Definition: vartype.c:6839
HRESULT WINAPI VarDateFromR8(double dblIn, DATE *pdateOut)
Definition: vartype.c:7353
#define swprintf
Definition: precomp.h:40
#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 wSecond
Definition: minwinbase.h:262
WORD wMinute
Definition: minwinbase.h:261
WORD wDayOfWeek
Definition: minwinbase.h:258
const char * LPCSTR
Definition: typedefs.h:52
const uint16_t * LPCWSTR
Definition: typedefs.h:57
HRESULT WINAPI VarUdateFromDate(DATE dateIn, ULONG dwFlags, UDATE *lpUdate)
Definition: variant.c:1404
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
#define LOCALE_SDATE
Definition: winnls.h:68
#define LOCALE_SDAYNAME1
Definition: winnls.h:87
#define LOCALE_SLONGDATE
Definition: winnls.h:71
#define LOCALE_S1159
Definition: winnls.h:81
#define LOCALE_SSHORTDATE
Definition: winnls.h:70
#define LOCALE_SMONTHNAME1
Definition: winnls.h:101
#define LOCALE_SABBREVMONTHNAME1
Definition: winnls.h:114
#define LOCALE_SABBREVDAYNAME1
Definition: winnls.h:94
#define LOCALE_IFIRSTDAYOFWEEK
Definition: winnls.h:85
#define LOCALE_STIME
Definition: winnls.h:69
#define LOCALE_S2359
Definition: winnls.h:82

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 1149 of file varformat.c.

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

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 1923 of file varformat.c.

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

424{
427
428 key.name = lpszFormat;
431 return fmt ? fmt->format : NULL;
432}
static const NAMED_FORMAT VARIANT_NamedFormats[]
Definition: varformat.c:397
static int __cdecl FormatCompareFn(const void *l, const void *r)
Definition: varformat.c:418
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 2532 of file varformat.c.

2533{
2534 DWORD localeValue;
2535 INT size;
2536
2537 if ((iMonth < 1) || (iMonth > 12))
2538 return E_INVALIDARG;
2539
2540 if (dwFlags)
2541 FIXME("Does not support flags %#lx, ignoring.\n", dwFlags);
2542
2543 if (fAbbrev)
2544 localeValue = LOCALE_SABBREVMONTHNAME1 + iMonth - 1;
2545 else
2546 localeValue = LOCALE_SMONTHNAME1 + iMonth - 1;
2547
2548 size = GetLocaleInfoW(LOCALE_USER_DEFAULT,localeValue, NULL, 0);
2549 if (!size) {
2550 ERR("GetLocaleInfo %#lx failed.\n", localeValue);
2552 }
2553 *pbstrOut = SysAllocStringLen(NULL,size - 1);
2554 if (!*pbstrOut)
2555 return E_OUTOFMEMORY;
2556 size = GetLocaleInfoW(LOCALE_USER_DEFAULT,localeValue, *pbstrOut, size);
2557 if (!size) {
2558 ERR("GetLocaleInfo of %#lx failed in 2nd stage?!\n", localeValue);
2559 SysFreeString(*pbstrOut);
2561 }
2562 return S_OK;
2563}
GLsizeiptr size
Definition: glext.h:5919
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:341
int32_t INT
Definition: typedefs.h:58
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210

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 475 of file varformat.c.

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

2585{
2586 DWORD localeValue;
2587 INT size;
2588
2589 /* Windows XP oleaut32.dll doesn't allow iWekday==0, contrary to MSDN */
2590 if (iWeekday < 1 || iWeekday > 7)
2591 return E_INVALIDARG;
2592 if (iFirstDay < 0 || iFirstDay > 7)
2593 return E_INVALIDARG;
2594 if (!pbstrOut)
2595 return E_INVALIDARG;
2596
2597 if (dwFlags)
2598 FIXME("Does not support flags %#lx, ignoring.\n", dwFlags);
2599
2600 /* If we have to use the default firstDay, find which one it is */
2601 if (iFirstDay == 0) {
2602 DWORD firstDay;
2603 localeValue = LOCALE_RETURN_NUMBER | LOCALE_IFIRSTDAYOFWEEK;
2605 (LPWSTR)&firstDay, sizeof(firstDay) / sizeof(WCHAR));
2606 if (!size) {
2607 ERR("GetLocaleInfo %#lx failed.\n", localeValue);
2609 }
2610 iFirstDay = firstDay + 2;
2611 }
2612
2613 /* Determine what we need to return */
2614 localeValue = fAbbrev ? LOCALE_SABBREVDAYNAME1 : LOCALE_SDAYNAME1;
2615 localeValue += (7 + iWeekday - 1 + iFirstDay - 2) % 7;
2616
2617 /* Determine the size of the data, allocate memory and retrieve the data */
2618 size = GetLocaleInfoW(LOCALE_USER_DEFAULT, localeValue, NULL, 0);
2619 if (!size) {
2620 ERR("GetLocaleInfo %#lx failed.\n", localeValue);
2622 }
2623 *pbstrOut = SysAllocStringLen(NULL, size - 1);
2624 if (!*pbstrOut)
2625 return E_OUTOFMEMORY;
2626 size = GetLocaleInfoW(LOCALE_USER_DEFAULT, localeValue, *pbstrOut, size);
2627 if (!size) {
2628 ERR("GetLocaleInfo %#lx failed in 2nd stage?!\n", localeValue);
2629 SysFreeString(*pbstrOut);
2631 }
2632 return S_OK;
2633}

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 347 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 361 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 271 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 342 of file varformat.c.

◆ fmtLongDate

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

Definition at line 292 of file varformat.c.

Referenced by VarFormatDateTime().

◆ fmtLongTime

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

Definition at line 314 of file varformat.c.

Referenced by VarFormatDateTime().

◆ fmtMediumDate

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

Definition at line 285 of file varformat.c.

◆ fmtMediumTime

const BYTE fmtMediumTime[0x11]
static
Initial value:

Definition at line 306 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:189

Definition at line 335 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 375 of file varformat.c.

◆ fmtScientific

const BYTE fmtScientific[0x13]
static
Initial value:

Definition at line 383 of file varformat.c.

◆ fmtShortDate

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

Definition at line 278 of file varformat.c.

Referenced by VarFormatDateTime().

◆ fmtShortTime

const BYTE fmtShortTime[0x0c]
static
Initial value:

Definition at line 299 of file varformat.c.

Referenced by VarFormatDateTime().

◆ fmtStandard

const BYTE fmtStandard[0x11]
static
Initial value:

Definition at line 368 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 321 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 328 of file varformat.c.

◆ VARIANT_NamedFormats

const NAMED_FORMAT VARIANT_NamedFormats[]
static
Initial value:
=
{
{ L"Currency", fmtCurrency },
{ L"Fixed", fmtFixed },
{ L"General Date", fmtGeneralDate },
{ L"General Number", fmtGeneralNumber },
{ L"Long Date", fmtLongDate },
{ L"Long Time", fmtLongTime },
{ L"Medium Date", fmtMediumDate },
{ L"Medium Time", fmtMediumTime },
{ L"On/Off", fmtOnOff },
{ L"Percent", fmtPercent },
{ L"Scientific", fmtScientific },
{ L"Short Date", fmtShortDate },
{ L"Short Time", fmtShortTime },
{ L"Standard", fmtStandard },
{ L"True/False", fmtTrueFalse },
{ L"Yes/No", fmtYesNo }
}
static const BYTE fmtPercent[0x15]
Definition: varformat.c:375
static const BYTE fmtYesNo[0x0d]
Definition: varformat.c:328
static const BYTE fmtGeneralNumber[sizeof(FMT_HEADER)]
Definition: varformat.c:342
static const BYTE fmtStandard[0x11]
Definition: varformat.c:368
static const BYTE fmtCurrency[0x26]
Definition: varformat.c:347
static const BYTE fmtOnOff[0x0d]
Definition: varformat.c:335
static const BYTE fmtMediumTime[0x11]
Definition: varformat.c:306
static const BYTE fmtTrueFalse[0x0d]
Definition: varformat.c:321
static const BYTE fmtMediumDate[0x0a]
Definition: varformat.c:285
static const BYTE fmtFixed[0x11]
Definition: varformat.c:361
static const BYTE fmtScientific[0x13]
Definition: varformat.c:383

Definition at line 397 of file varformat.c.

Referenced by VARIANT_GetNamedFormat().