This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Perl_sv_vcatpvfn_flags: set locale at most once
Calls to external snprintf-ish functions or that directly access
PL_numeric_radix_sv are supposed to sandwich this access within
STORE_LC_NUMERIC_SET_TO_NEEDED();
....
RESTORE_LC_NUMERIC();
The code in Perl_sv_vcatpvfn_flags() seems to have gotten a bit confused
as to whether its trying to only set STORE_LC_NUMERIC_SET_TO_NEEDED()
once, then handle one of more %[aefh] format elements, then only
restore on exit. There is code at the end of the function which says:
RESTORE_LC_NUMERIC(); /* Done outside loop, so don't have to save/restore
each iteration. */
but in practice various places within this function (and its helper
function S_format_hexfp() inconsistently repeatedly do
STORE_LC_NUMERIC_SET_TO_NEEDED(); and sometime do RESTORE_LC_NUMERIC().
This commit changes it so that STORE_LC_NUMERIC_SET_TO_NEEDED() is called
at most once, the first time a % format involving a radix point is
encountered, and does RESTORE_LC_NUMERIC(); exactly once at the end of the
function.
Note that while calling STORE_LC_NUMERIC_SET_TO_NEEDED() multiple times
is harmless, its quite expensive, as each time it has to check whether
it's in the scope of 'use locale'. RESTORE_LC_NUMERIC() is cheap if
STORE_LC_NUMERIC_SET_TO_NEEDED() earlier determined that there was nothing
to do.