http://bugs.winehq.org/show_bug.cgi?id=8095
------- Additional Comments From focht@gmx.net 2007-18-04 11:25 ------- Hello,
it's a bug in oleaut32's varformat.c/VarTokenizeFormatString(). I used "WINEDEBUG=+seh,+ole,+variant" for more info.
--- snip --- 0009:Call oleaut32.VarFormat(0034f51c,012f15a4,00000001,00000001,00000000,0034f3b8) ret=660f587b trace:variant:VarFormat (0x34f51c->(VT_I2|VT_BYREF),L"##rd harmonic",1,1,0x00000000,0x34f3b8) trace:variant:VarTokenizeFormatString (L"##rd harmonic",0x34f1dc,256,1,1,0x00000400,(nil)) trace:variant:VarTokenizeFormatString 2 #'s trace:variant:VarTokenizeFormatString New copy (char 'r') trace:variant:VarTokenizeFormatString extend copy (char 'd'), length now 2 trace:variant:VarTokenizeFormatString extend copy (char ' '), length now 3 trace:variant:VarTokenizeFormatString extend copy (char 'h'), length now 4 trace:variant:VarTokenizeFormatString extend copy (char 'a'), length now 5 trace:variant:VarTokenizeFormatString extend copy (char 'r'), length now 6 trace:variant:VarTokenizeFormatString extend copy (char 'm'), length now 7 trace:variant:VarTokenizeFormatString extend copy (char 'o'), length now 8 trace:variant:VarTokenizeFormatString extend copy (char 'n'), length now 9 trace:variant:VarTokenizeFormatString extend copy (char 'i'), length now 10 trace:variant:VarTokenizeFormatString gen date trace:variant:VarTokenizeFormatString extend copy (char 'E'), length now 6 trace:variant:VarTokenizeFormatString extend copy (char '°'), length now 7 trace:variant:VarTokenizeFormatString extend copy (char '4'), length now 8 trace:variant:VarTokenizeFormatString extend copy (char '@'), length now 9 trace:variant:VarTokenizeFormatString extend copy (char ''), length now 10 trace:variant:VarFormatFromTokens (0x34f51c,L"##rd harmonic",0x34f1dc,0,0x34f3b8,0x00000400) trace:variant:VARIANT_FormatDate (0x34f51c->(VT_I2|VT_BYREF),L"##rd harmonic",0x34f1dc,0x00000000,0x34f3b8,0x00000400) trace:variant:VariantChangeTypeEx (0x34f150->(VT_EMPTY),0x34f51c->(VT_I2|VT_BYREF),0x00000409,0x0000,VT_DATE) trace:variant:VariantClear (0x34ecc0->(VT_EMPTY)) trace:variant:VariantClear (0x34ecb0->(VT_EMPTY)) trace:variant:VariantCopyInd (0x34ecb0->(VT_EMPTY),0x34f51c->(VT_I2|VT_BYREF)) trace:variant:VariantClear (0x34ecb0->(VT_EMPTY)) trace:variant:VariantCopyInd returning 0x00000000, 0x34ecb0->(VT_I2) trace:variant:VARIANT_Coerce (0x34ecc0->(VT_EMPTY),0x00000409,0x0000,0x34ecb0->(VT_I2),VT_DATE) trace:variant:VariantCopy (0x34f150->(VT_EMPTY),0x34ecc0->(VT_DATE)) trace:variant:VariantClear (0x34f150->(VT_EMPTY)) trace:variant:VariantClear (0x34ecc0->(VT_DATE)) trace:variant:VariantClear (0x34ecb0->(VT_I2)) trace:variant:VariantChangeTypeEx returning 0x00000000, 0x34f150->(VT_DATE) trace:variant:VarUdateFromDate (3,0x00000000,0x34f128) err:variant:VARIANT_FormatDate Unknown token 0x35! --- snip ---
String: L"##rd harmonic" should tokenize to: "2 digits" (FMT_TYPE_NUMBER) and "string literal" FMT_GEN_COPY (with FMT_STATE_OPEN_COPY flag). The format string tokenizer incorrectly ignores the "literal" state while parsing within the literal. It takes last char of literal "c" as FMT_TYPE_DATE (date) which brings the parser out of sync (see trace). The date type conversion/coercion later is due to buggy parsing.
Fixing the "general date format"/"else if (*pFormat == 'c' || *pFormat == 'C')" part isnt enough. The VarTokenizeFormatString() tokenizer has a general problem: the actual variant type isnt taken into account (which could serve as hint).
To overcome "literal-or-not" parsing AI limitation, i think it's best to use the actual variant type (1st param) passed into VarFormat(). No ambiguities. Example: (VT_I2|VT_BYREF) -> it's obvious, that one of the tokens must be integer (##) but can't be general date format (c).
VarTokenizeFormatString() needs to be modified to receive information of expected token types too.
Regards