Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
25cc6ff6
Commit
25cc6ff6
authored
Aug 06, 2020
by
Piotr Caban
Committed by
Alexandre Julliard
Aug 06, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ucrtbase: Support _CRT_INTERNAL_PRINTF_STANDARD_ROUNDING flag in printf.
Signed-off-by:
Piotr Caban
<
piotr@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
04de6fe3
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
78 additions
and
14 deletions
+78
-14
msvcrt.h
dlls/msvcrt/msvcrt.h
+2
-1
printf.h
dlls/msvcrt/printf.h
+67
-11
printf.c
dlls/ucrtbase/tests/printf.c
+8
-2
corecrt_stdio_config.h
include/msvcrt/corecrt_stdio_config.h
+1
-0
No files found.
dlls/msvcrt/msvcrt.h
View file @
25cc6ff6
...
...
@@ -1312,8 +1312,9 @@ extern char* __cdecl __unDName(char *,const char*,int,malloc_func_t,free_func_t,
#define UCRTBASE_PRINTF_LEGACY_WIDE_SPECIFIERS (0x0004)
#define UCRTBASE_PRINTF_LEGACY_MSVCRT_COMPATIBILITY (0x0008)
#define UCRTBASE_PRINTF_LEGACY_THREE_DIGIT_EXPONENTS (0x0010)
#define UCRTBASE_PRINTF_STANDARD_ROUNDING (0x0020)
#define UCRTBASE_PRINTF_MASK (0x00
1
F)
#define UCRTBASE_PRINTF_MASK (0x00
3
F)
#define MSVCRT_PRINTF_POSITIONAL_PARAMS (0x0100)
#define MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER (0x0200)
...
...
dlls/msvcrt/printf.h
View file @
25cc6ff6
...
...
@@ -401,7 +401,7 @@ static inline int FUNC_NAME(pf_output_special_fp)(FUNC_NAME(puts_clbk) pf_puts,
}
static
inline
int
FUNC_NAME
(
pf_output_hex_fp
)(
FUNC_NAME
(
puts_clbk
)
pf_puts
,
void
*
puts_ctx
,
double
v
,
pf_flags
*
flags
,
MSVCRT__locale_t
locale
)
double
v
,
pf_flags
*
flags
,
MSVCRT__locale_t
locale
,
BOOL
standard_rounding
)
{
const
APICHAR
digits
[
2
][
16
]
=
{
{
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
},
...
...
@@ -449,7 +449,25 @@ static inline int FUNC_NAME(pf_output_hex_fp)(FUNC_NAME(puts_clbk) pf_puts, void
if
(
p
[
0
]
>=
'8'
)
p
[
-
2
]
++
;
if
(
!
flags
->
Alternate
)
p
--
;
}
else
if
(
flags
->
Precision
>
0
&&
flags
->
Precision
<
MANT_BITS
/
4
)
{
BOOL
round_up
=
(
p
[
flags
->
Precision
]
>=
'8'
);
BOOL
round_up
=
FALSE
;
if
(
!
standard_rounding
)
round_up
=
(
p
[
flags
->
Precision
]
>=
'8'
);
else
if
(
p
[
flags
->
Precision
]
>
'8'
)
round_up
=
TRUE
;
else
if
(
p
[
flags
->
Precision
]
==
'8'
)
{
for
(
r
=
flags
->
Precision
+
1
;
r
<
MANT_BITS
/
4
;
r
++
)
{
if
(
p
[
r
]
!=
'0'
)
{
round_up
=
TRUE
;
break
;
}
}
if
(
!
round_up
)
{
if
(
p
[
flags
->
Precision
-
1
]
<=
'9'
)
round_up
=
(
p
[
flags
->
Precision
-
1
]
-
'0'
)
&
1
;
else
if
(
p
[
flags
->
Precision
-
1
]
<=
'F'
)
round_up
=
(
p
[
flags
->
Precision
-
1
]
-
'A'
)
&
1
;
else
round_up
=
(
p
[
flags
->
Precision
-
1
]
-
'a'
)
&
1
;
}
}
for
(
r
=
flags
->
Precision
-
1
;
r
>=
0
&&
round_up
;
r
--
)
{
round_up
=
FALSE
;
if
(
p
[
r
]
==
'f'
||
p
[
r
]
==
'F'
)
{
...
...
@@ -574,13 +592,14 @@ static inline void FUNC_NAME(pf_integer_conv)(APICHAR *buf, pf_flags *flags, LON
}
static
inline
int
FUNC_NAME
(
pf_output_fp
)(
FUNC_NAME
(
puts_clbk
)
pf_puts
,
void
*
puts_ctx
,
double
v
,
pf_flags
*
flags
,
MSVCRT__locale_t
locale
,
BOOL
three_digit_exp
)
double
v
,
pf_flags
*
flags
,
MSVCRT__locale_t
locale
,
BOOL
three_digit_exp
,
BOOL
standard_rounding
)
{
int
e2
,
e10
=
0
,
round_pos
,
round_limb
,
radix_pos
,
first_limb_len
,
i
,
len
,
r
,
ret
;
BYTE
bnum_data
[
FIELD_OFFSET
(
struct
bnum
,
data
[
BNUM_PREC64
])];
struct
bnum
*
b
=
(
struct
bnum
*
)
bnum_data
;
APICHAR
buf
[
LIMB_DIGITS
+
1
];
BOOL
trim_tail
=
FALSE
;
BOOL
trim_tail
=
FALSE
,
round_up
=
FALSE
;
pf_flags
f
;
int
limb_len
,
prec
;
ULONGLONG
m
;
...
...
@@ -637,8 +656,6 @@ static inline int FUNC_NAME(pf_output_fp)(FUNC_NAME(puts_clbk) pf_puts, void *pu
round_limb
=
b
->
e
-
(
round_pos
-
first_limb_len
-
1
)
/
LIMB_DIGITS
-
2
;
if
(
b
->
b
<=
round_limb
&&
round_limb
<
b
->
e
)
{
BOOL
round_up
=
FALSE
;
if
(
round_pos
<=
first_limb_len
)
{
round_pos
=
first_limb_len
-
round_pos
;
}
else
{
...
...
@@ -649,9 +666,31 @@ static inline int FUNC_NAME(pf_output_fp)(FUNC_NAME(puts_clbk) pf_puts, void *pu
if
(
round_pos
)
{
l
=
b
->
data
[
bnum_idx
(
b
,
round_limb
)]
%
p10s
[
round_pos
];
b
->
data
[
bnum_idx
(
b
,
round_limb
)]
-=
l
;
if
(
2
*
l
>=
p10s
[
round_pos
])
round_up
=
TRUE
;
if
(
!
standard_rounding
)
round_up
=
(
2
*
l
>=
p10s
[
round_pos
]);
else
if
(
2
*
l
>
p10s
[
round_pos
])
round_up
=
TRUE
;
else
if
(
2
*
l
==
p10s
[
round_pos
])
{
for
(
r
=
round_limb
-
1
;
r
>=
b
->
b
;
r
--
)
{
if
(
b
->
data
[
bnum_idx
(
b
,
r
)])
{
round_up
=
TRUE
;
break
;
}
}
if
(
!
round_up
)
round_up
=
b
->
data
[
bnum_idx
(
b
,
round_limb
)]
/
p10s
[
round_pos
]
&
1
;
}
}
else
if
(
round_limb
-
1
>=
b
->
b
)
{
if
(
2
*
b
->
data
[
bnum_idx
(
b
,
round_limb
-
1
)]
>=
LIMB_MAX
)
round_up
=
TRUE
;
if
(
!
standard_rounding
)
round_up
=
(
2
*
b
->
data
[
bnum_idx
(
b
,
round_limb
-
1
)]
>=
LIMB_MAX
);
else
if
(
2
*
b
->
data
[
bnum_idx
(
b
,
round_limb
-
1
)]
>
LIMB_MAX
)
round_up
=
TRUE
;
else
if
(
2
*
b
->
data
[
bnum_idx
(
b
,
round_limb
-
1
)]
==
LIMB_MAX
)
{
for
(
r
=
round_limb
-
2
;
r
>=
b
->
b
;
r
--
)
{
if
(
b
->
data
[
bnum_idx
(
b
,
r
)])
{
round_up
=
TRUE
;
break
;
}
}
if
(
!
round_up
)
round_up
=
b
->
data
[
bnum_idx
(
b
,
round_limb
)]
&
1
;
}
}
b
->
b
=
round_limb
;
...
...
@@ -681,7 +720,20 @@ static inline int FUNC_NAME(pf_output_fp)(FUNC_NAME(puts_clbk) pf_puts, void *pu
}
}
else
if
(
b
->
e
<=
round_limb
)
{
/* got 0 or 1 after rounding */
b
->
data
[
bnum_idx
(
b
,
round_limb
)]
=
b
->
e
==
round_limb
&&
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)]
>=
LIMB_MAX
/
2
;
if
(
b
->
e
==
round_limb
)
{
if
(
!
standard_rounding
)
round_up
=
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)]
>=
LIMB_MAX
/
2
;
else
if
(
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)]
>
LIMB_MAX
/
2
)
round_up
=
TRUE
;
else
if
(
b
->
data
[
bnum_idx
(
b
,
b
->
e
-
1
)]
==
LIMB_MAX
/
2
)
{
for
(
r
=
b
->
e
-
2
;
r
>=
b
->
b
;
r
--
)
{
if
(
b
->
data
[
bnum_idx
(
b
,
r
)])
{
round_up
=
TRUE
;
break
;
}
}
}
}
b
->
data
[
bnum_idx
(
b
,
round_limb
)]
=
round_up
;
b
->
b
=
round_limb
;
b
->
e
=
b
->
b
+
1
;
first_limb_len
=
1
;
...
...
@@ -918,9 +970,11 @@ int FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, const API
BOOL
legacy_wide
=
options
&
UCRTBASE_PRINTF_LEGACY_WIDE_SPECIFIERS
;
BOOL
legacy_msvcrt_compat
=
options
&
UCRTBASE_PRINTF_LEGACY_MSVCRT_COMPATIBILITY
;
BOOL
three_digit_exp
=
options
&
UCRTBASE_PRINTF_LEGACY_THREE_DIGIT_EXPONENTS
;
BOOL
standard_rounding
=
options
&
UCRTBASE_PRINTF_STANDARD_ROUNDING
;
#else
BOOL
legacy_wide
=
TRUE
,
legacy_msvcrt_compat
=
TRUE
;
BOOL
three_digit_exp
=
MSVCRT__get_output_format
()
!=
MSVCRT__TWO_DIGIT_EXPONENT
;
BOOL
standard_rounding
=
FALSE
;
#endif
TRACE
(
"Format is: %s
\n
"
,
FUNC_NAME
(
debugstr
)(
fmt
));
...
...
@@ -1136,9 +1190,11 @@ int FUNC_NAME(pf_printf)(FUNC_NAME(puts_clbk) pf_puts, void *puts_ctx, const API
i
=
FUNC_NAME
(
pf_output_special_fp
)(
pf_puts
,
puts_ctx
,
val
,
&
flags
,
locale
,
legacy_msvcrt_compat
,
three_digit_exp
);
else
if
(
flags
.
Format
==
'a'
||
flags
.
Format
==
'A'
)
i
=
FUNC_NAME
(
pf_output_hex_fp
)(
pf_puts
,
puts_ctx
,
val
,
&
flags
,
locale
);
i
=
FUNC_NAME
(
pf_output_hex_fp
)(
pf_puts
,
puts_ctx
,
val
,
&
flags
,
locale
,
standard_rounding
);
else
i
=
FUNC_NAME
(
pf_output_fp
)(
pf_puts
,
puts_ctx
,
val
,
&
flags
,
locale
,
three_digit_exp
);
i
=
FUNC_NAME
(
pf_output_fp
)(
pf_puts
,
puts_ctx
,
val
,
&
flags
,
locale
,
three_digit_exp
,
standard_rounding
);
}
else
{
if
(
invoke_invalid_param_handler
)
{
MSVCRT__invalid_parameter
(
NULL
,
NULL
,
NULL
,
0
,
0
);
...
...
dlls/ucrtbase/tests/printf.c
View file @
25cc6ff6
...
...
@@ -655,7 +655,10 @@ static void test_printf_fp(void)
_CRT_INTERNAL_PRINTF_LEGACY_MSVCRT_COMPATIBILITY
,
_CRT_INTERNAL_PRINTF_LEGACY_THREE_DIGIT_EXPONENTS
,
_CRT_INTERNAL_PRINTF_LEGACY_MSVCRT_COMPATIBILITY
|
_CRT_INTERNAL_PRINTF_LEGACY_THREE_DIGIT_EXPONENTS
,
_CRT_INTERNAL_PRINTF_LEGACY_MSVCRT_COMPATIBILITY
|
_CRT_INTERNAL_PRINTF_LEGACY_THREE_DIGIT_EXPONENTS
|
_CRT_INTERNAL_PRINTF_STANDARD_ROUNDING
};
const
struct
{
const
char
*
fmt
;
...
...
@@ -759,9 +762,9 @@ static void test_printf_fp(void)
{
"%#.0a"
,
-
0
.
5
,
{
"-0x1.p-1"
}},
{
"%#.0a"
,
0
.
5
,
{
"0x1.p-1"
}},
{
"%#.0a"
,
1
.
5
,
{
"0x2.p+0"
},
{
"0x1.p+0"
}},
{
"%#.1a"
,
1
.
03125
,
{
"0x1.1p+0"
},
{
"0x1.0p+0"
}},
{
"%#.1a"
,
1
.
03125
,
{
"0x1.1p+0"
,
NULL
,
NULL
,
NULL
,
"0x1.0p+0"
},
{
"0x1.0p+0"
}},
{
"%#.1a"
,
1
.
09375
,
{
"0x1.2p+0"
},
{
"0x1.1p+0"
}},
{
"%#.1a"
,
1
.
15625
,
{
"0x1.3p+0"
},
{
"0x1.2p+0"
}},
{
"%#.1a"
,
1
.
15625
,
{
"0x1.3p+0"
,
NULL
,
NULL
,
NULL
,
"0x1.2p+0"
},
{
"0x1.2p+0"
}},
{
"%f"
,
0
,
{
"0.000000"
}},
{
"%e"
,
0
,
{
"0.000000e+00"
,
NULL
,
"0.000000e+000"
}},
...
...
@@ -813,6 +816,9 @@ static void test_printf_fp(void)
{
"%.30f"
,
1
.
0
/
3
.
0
,
{
"0.333333333333333314829616256247"
}},
{
"%.30lf"
,
sqrt
(
2
),
{
"1.414213562373095145474621858739"
}},
{
"%.0g"
,
9.8949714229143402e-05
,
{
"0.0001"
}},
{
"%.0f"
,
0
.
5
,
{
"1"
,
NULL
,
NULL
,
NULL
,
"0"
},
{
NULL
,
NULL
,
NULL
,
NULL
,
"1"
}},
{
"%.0f"
,
1
.
5
,
{
"2"
}},
{
"%.0f"
,
2
.
5
,
{
"3"
,
NULL
,
NULL
,
NULL
,
"2"
},
{
NULL
,
NULL
,
NULL
,
NULL
,
"3"
}},
};
const
char
*
res
=
NULL
;
...
...
include/msvcrt/corecrt_stdio_config.h
View file @
25cc6ff6
...
...
@@ -14,6 +14,7 @@
#define _CRT_INTERNAL_PRINTF_LEGACY_WIDE_SPECIFIERS 0x0004ULL
#define _CRT_INTERNAL_PRINTF_LEGACY_MSVCRT_COMPATIBILITY 0x0008ULL
#define _CRT_INTERNAL_PRINTF_LEGACY_THREE_DIGIT_EXPONENTS 0x0010ULL
#define _CRT_INTERNAL_PRINTF_STANDARD_ROUNDING 0x0020ULL
#define _CRT_INTERNAL_SCANF_SECURECRT 0x0001ULL
#define _CRT_INTERNAL_SCANF_LEGACY_WIDE_SPECIFIERS 0x0002ULL
...
...
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