Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
c638730b
Commit
c638730b
authored
Jun 08, 2020
by
Piotr Caban
Committed by
Alexandre Julliard
Jun 08, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msvcrt: Reimplement special doubles printing.
Signed-off-by:
Piotr Caban
<
piotr@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
bfa1e3ef
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
141 additions
and
77 deletions
+141
-77
printf.h
dlls/msvcrt/printf.h
+141
-77
No files found.
dlls/msvcrt/printf.h
View file @
c638730b
...
...
@@ -82,7 +82,7 @@ static inline int FUNC_NAME(pf_fill)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ct
{
int
i
,
r
=
0
,
written
;
if
(
flags
->
Sign
&&
!
strchr
(
"diaeEfFgG"
,
flags
->
Format
))
if
(
flags
->
Sign
&&
!
strchr
(
"dia
A
eEfFgG"
,
flags
->
Format
))
flags
->
Sign
=
0
;
if
(
left
&&
flags
->
Sign
)
{
...
...
@@ -276,6 +276,135 @@ static inline int FUNC_NAME(pf_handle_string)(FUNC_NAME(puts_clbk) pf_puts, void
return
FUNC_NAME
(
pf_output_format_wstr
)(
pf_puts
,
puts_ctx
,
str
,
len
,
flags
,
locale
);
}
static
inline
int
FUNC_NAME
(
pf_output_special_fp
)(
FUNC_NAME
(
puts_clbk
)
pf_puts
,
void
*
puts_ctx
,
double
v
,
FUNC_NAME
(
pf_flags
)
*
flags
,
MSVCRT__locale_t
locale
,
BOOL
legacy_msvcrt_compat
,
BOOL
three_digit_exp
)
{
APICHAR
pfx
[
16
],
sfx
[
8
],
*
p
;
int
len
=
0
,
r
,
frac_len
,
pfx_len
,
sfx_len
;
if
(
!
legacy_msvcrt_compat
)
{
const
char
*
str
;
if
(
isinf
(
v
))
{
if
(
strchr
(
"AEFG"
,
flags
->
Format
))
str
=
"INF"
;
else
str
=
"inf"
;
}
else
{
if
(
strchr
(
"AEFG"
,
flags
->
Format
))
str
=
(
flags
->
Sign
==
'-'
?
"NAN(IND)"
:
"NAN"
);
else
str
=
(
flags
->
Sign
==
'-'
?
"nan(ind)"
:
"nan"
);
}
flags
->
Precision
=
-
1
;
flags
->
PadZero
=
0
;
return
FUNC_NAME
(
pf_output_format_str
)(
pf_puts
,
puts_ctx
,
str
,
-
1
,
flags
,
locale
);
}
/* workaround a bug in native implementation */
if
(
flags
->
Format
==
'g'
||
flags
->
Format
==
'G'
)
flags
->
Precision
--
;
p
=
pfx
;
if
(
flags
->
PadZero
&&
(
flags
->
Format
==
'a'
||
flags
->
Format
==
'A'
))
{
if
(
flags
->
Sign
)
*
p
++
=
flags
->
Sign
;
*
p
++
=
'0'
;
*
p
++
=
(
flags
->
Format
==
'a'
?
'x'
:
'X'
);
r
=
pf_puts
(
puts_ctx
,
p
-
pfx
,
pfx
);
if
(
r
<
0
)
return
r
;
len
+=
r
;
flags
->
FieldLength
-=
p
-
pfx
;
}
p
=
pfx
;
if
(
!
flags
->
PadZero
&&
(
flags
->
Format
==
'a'
||
flags
->
Format
==
'A'
))
{
*
p
++
=
'0'
;
*
p
++
=
(
flags
->
Format
==
'a'
?
'x'
:
'X'
);
}
*
p
++
=
'1'
;
*
p
++
=
*
(
locale
?
locale
->
locinfo
:
get_locinfo
())
->
lconv
->
decimal_point
;
*
p
++
=
'#'
;
frac_len
=
1
;
if
(
isinf
(
v
))
{
*
p
++
=
'I'
;
*
p
++
=
'N'
;
*
p
++
=
'F'
;
frac_len
+=
3
;
}
else
if
(
flags
->
Sign
==
'-'
)
{
*
p
++
=
'I'
;
*
p
++
=
'N'
;
*
p
++
=
'D'
;
frac_len
+=
3
;
}
else
{
*
p
++
=
'Q'
;
*
p
++
=
'N'
;
*
p
++
=
'A'
;
*
p
++
=
'N'
;
frac_len
+=
4
;
}
*
p
=
0
;
pfx_len
=
p
-
pfx
;
if
(
len
)
flags
->
Sign
=
0
;
if
(
flags
->
Precision
>=
0
&&
flags
->
Precision
<
frac_len
)
p
[
flags
->
Precision
-
frac_len
-
1
]
++
;
p
=
sfx
;
if
(
strchr
(
"aAeE"
,
flags
->
Format
))
{
if
(
flags
->
Format
==
'a'
)
*
p
++
=
'p'
;
else
if
(
flags
->
Format
==
'A'
)
*
p
++
=
'P'
;
else
if
(
flags
->
Format
==
'e'
)
*
p
++
=
'e'
;
else
*
p
++
=
'E'
;
*
p
++
=
'+'
;
*
p
++
=
'0'
;
if
(
flags
->
Format
==
'e'
||
flags
->
Format
==
'E'
)
{
*
p
++
=
'0'
;
if
(
three_digit_exp
)
*
p
++
=
'0'
;
}
}
*
p
=
0
;
if
(
!
flags
->
Alternate
&&
(
flags
->
Format
==
'g'
||
flags
->
Format
==
'G'
))
sfx_len
=
frac_len
;
else
sfx_len
=
flags
->
Precision
;
if
(
sfx_len
==
-
1
)
{
if
(
strchr
(
"fFeE"
,
flags
->
Format
))
sfx_len
=
6
;
else
if
(
flags
->
Format
==
'a'
||
flags
->
Format
==
'A'
)
sfx_len
=
13
;
}
sfx_len
+=
p
-
sfx
-
frac_len
;
if
(
sfx_len
>
0
)
flags
->
FieldLength
-=
sfx_len
;
if
(
flags
->
Precision
>=
0
)
{
if
(
!
flags
->
Precision
)
flags
->
Precision
--
;
flags
->
Precision
+=
pfx_len
-
frac_len
;
}
#ifdef PRINTF_WIDE
r
=
FUNC_NAME
(
pf_output_format_wstr
)(
pf_puts
,
puts_ctx
,
pfx
,
-
1
,
flags
,
locale
);
#else
r
=
FUNC_NAME
(
pf_output_format_str
)(
pf_puts
,
puts_ctx
,
pfx
,
-
1
,
flags
,
locale
);
#endif
if
(
r
<
0
)
return
r
;
len
+=
r
;
flags
->
FieldLength
=
sfx_len
;
flags
->
PadZero
=
'0'
;
flags
->
Precision
=
-
1
;
flags
->
Sign
=
0
;
#ifdef PRINTF_WIDE
r
=
FUNC_NAME
(
pf_output_format_wstr
)(
pf_puts
,
puts_ctx
,
sfx
,
-
1
,
flags
,
locale
);
#else
r
=
FUNC_NAME
(
pf_output_format_str
)(
pf_puts
,
puts_ctx
,
sfx
,
-
1
,
flags
,
locale
);
#endif
if
(
r
<
0
)
return
r
;
len
+=
r
;
return
len
;
}
static
inline
void
FUNC_NAME
(
pf_rebuild_format_string
)(
char
*
p
,
FUNC_NAME
(
pf_flags
)
*
flags
)
{
*
p
++
=
'%'
;
...
...
@@ -606,42 +735,26 @@ int FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, const API
#endif
if
(
tmp
!=
buf
)
HeapFree
(
GetProcessHeap
(),
0
,
tmp
);
}
else
if
(
flags
.
Format
&&
strchr
(
"aeEfFgG"
,
flags
.
Format
))
{
}
else
if
(
flags
.
Format
&&
strchr
(
"a
A
eEfFgG"
,
flags
.
Format
))
{
char
float_fmt
[
20
],
buf_a
[
32
],
*
tmp
=
buf_a
,
*
decimal_point
;
int
len
=
flags
.
Precision
+
10
;
double
val
=
pf_args
(
args_ctx
,
pos
,
VT_R8
,
valist
).
get_double
;
int
r
;
BOOL
inf
=
FALSE
,
nan
=
FALSE
,
ind
=
FALSE
;
if
(
isinf
(
val
))
inf
=
TRUE
;
else
if
(
isnan
(
val
))
{
if
(
!
signbit
(
val
))
nan
=
TRUE
;
else
ind
=
TRUE
;
}
if
(
inf
||
nan
||
ind
)
{
if
(
ind
||
val
<
0
)
if
(
signbit
(
val
))
{
flags
.
Sign
=
'-'
;
if
(
flags
.
Format
==
'g'
||
flags
.
Format
==
'G'
)
val
=
(
nan
?
1
.
12345
:
1
.
1234
);
/* fraction will be overwritten with #INF, #IND or #QNAN string */
else
val
=
1
;
if
(
flags
.
Format
==
'a'
)
{
if
(
flags
.
Precision
==-
1
)
flags
.
Precision
=
6
;
/* strlen("#INF00") */
}
val
=
-
val
;
}
if
(
isinf
(
val
)
||
isnan
(
val
))
i
=
FUNC_NAME
(
pf_output_special_fp
)(
pf_puts
,
puts_ctx
,
val
,
&
flags
,
locale
,
legacy_msvcrt_compat
,
three_digit_exp
);
else
{
if
(
flags
.
Format
==
'f'
||
flags
.
Format
==
'F'
)
{
if
(
val
>-
10
.
0
&&
val
<
10
.
0
)
if
(
val
<
10
.
0
)
i
=
1
;
else
i
=
1
+
log10
(
val
<
0
?
-
val
:
val
);
i
=
1
+
log10
(
val
);
/* Default precision is 6, additional space for sign, separator and nullbyte is required */
i
+=
(
flags
.
Precision
==-
1
?
6
:
flags
.
Precision
)
+
3
;
...
...
@@ -655,65 +768,15 @@ int FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, const API
return
-
1
;
FUNC_NAME
(
pf_rebuild_format_string
)(
float_fmt
,
&
flags
);
if
(
val
<
0
)
{
flags
.
Sign
=
'-'
;
val
=
-
val
;
}
if
((
inf
||
nan
||
ind
)
&&
!
legacy_msvcrt_compat
)
{
static
const
char
inf_str
[]
=
"inf"
;
static
const
char
ind_str
[]
=
"nan(ind)"
;
static
const
char
nan_str
[]
=
"nan"
;
if
(
inf
)
memcpy
(
tmp
,
inf_str
,
ARRAY_SIZE
(
inf_str
));
else
if
(
ind
)
memcpy
(
tmp
,
ind_str
,
ARRAY_SIZE
(
ind_str
));
else
memcpy
(
tmp
,
nan_str
,
ARRAY_SIZE
(
nan_str
));
if
(
strchr
(
"EFG"
,
flags
.
Format
))
for
(
i
=
0
;
tmp
[
i
];
i
++
)
tmp
[
i
]
=
MSVCRT__toupper_l
(
tmp
[
i
],
NULL
);
}
else
{
sprintf
(
tmp
,
float_fmt
,
val
);
if
(
MSVCRT__toupper_l
(
flags
.
Format
,
NULL
)
==
'E'
||
MSVCRT__toupper_l
(
flags
.
Format
,
NULL
)
==
'G'
)
FUNC_NAME
(
pf_fixup_exponent
)(
tmp
,
three_digit_exp
);
}
decimal_point
=
strchr
(
tmp
,
'.'
);
if
(
decimal_point
)
{
if
(
decimal_point
)
*
decimal_point
=
*
(
locale
?
locale
->
locinfo
:
get_locinfo
())
->
lconv
->
decimal_point
;
if
(
inf
||
nan
||
ind
)
{
static
const
char
inf_str
[]
=
"#INF"
;
static
const
char
ind_str
[]
=
"#IND"
;
static
const
char
nan_str
[]
=
"#QNAN"
;
const
char
*
str
;
int
size
;
if
(
inf
)
{
str
=
inf_str
;
size
=
sizeof
(
inf_str
);
}
else
if
(
ind
)
{
str
=
ind_str
;
size
=
sizeof
(
ind_str
);
}
else
{
str
=
nan_str
;
size
=
sizeof
(
nan_str
);
}
for
(
i
=
1
;
i
<
size
;
i
++
)
{
if
(
decimal_point
[
i
]
<
'0'
||
decimal_point
[
i
]
>
'9'
)
break
;
decimal_point
[
i
]
=
str
[
i
-
1
];
}
if
(
i
!=
size
&&
i
!=
1
)
decimal_point
[
i
-
1
]
++
;
}
}
len
=
strlen
(
tmp
);
i
=
FUNC_NAME
(
pf_fill
)(
pf_puts
,
puts_ctx
,
len
,
&
flags
,
TRUE
);
if
(
i
<
0
)
...
...
@@ -728,6 +791,7 @@ int FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, const API
if
(
r
<
0
)
return
r
;
i
+=
r
;
}
}
else
{
if
(
invoke_invalid_param_handler
)
{
MSVCRT__invalid_parameter
(
NULL
,
NULL
,
NULL
,
0
,
0
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment