Skip to content

Commit

Permalink
vutil.c: Simplify locale handling
Browse files Browse the repository at this point in the history
I read the code over and realized that there was a much simpler way to
do things.
  • Loading branch information
khwilliamson committed Apr 29, 2021
1 parent 55b87ff commit ae03410
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 60 deletions.
2 changes: 1 addition & 1 deletion t/porting/customized.dat
Expand Up @@ -25,5 +25,5 @@ Win32API::File cpan/Win32API-File/File.pm 8fd212857f821cb26648878b96e57f13bf21b9
Win32API::File cpan/Win32API-File/File.xs beb870fed4490d2faa547b4a8576b8d64d1d27c5
experimental cpan/experimental/t/basic.t cb9da8dd05b854375809872a05dd32637508d5da
version cpan/version/lib/version.pm 9a4d4c2a89cc95c0c946de6742d6df41e546c12c
version vutil.c 88855f7eb6ce443f57565d287ff2a0bbcd443bd2
version vutil.c 0c2a989d41de7e398b8ca745f4e0fe8714894694
version vxs.inc d23e4fac6211d3b35b367e80ef23b8ab5fa9d0eb
67 changes: 8 additions & 59 deletions vutil.c
Expand Up @@ -628,11 +628,15 @@ Perl_upg_version(pTHX_ SV *ver, bool qv)
* locales without letting perl know, therefore we have to find it
* from first principals. See [perl #121930]. */

# ifdef USE_POSIX_2008_LOCALE

/* Its easiest with POSIX 2008: Just save the initial locale and
* toggle to C */
const locale_t locale_obj_on_entry
= uselocale((locale_t) PL_C_locale_obj);
# else
/* In windows, or not threaded, or not thread-safe, if it isn't C,
* set it to C. */

# ifndef USE_POSIX_2008_LOCALE

const char * locale_name_on_entry;

LC_NUMERIC_LOCK(0); /* Start critical section */
Expand All @@ -649,49 +653,6 @@ Perl_upg_version(pTHX_ SV *ver, bool qv)
change the locale */
locale_name_on_entry = NULL;
}

# else

const locale_t locale_obj_on_entry = uselocale((locale_t) 0);
const char * locale_name_on_entry = NULL;
DECLARATION_FOR_LC_NUMERIC_MANIPULATION;

if (locale_obj_on_entry == LC_GLOBAL_LOCALE) {

/* in the global locale, we can call system setlocale and if it
* isn't C, set it to C. */
LC_NUMERIC_LOCK(0);

locale_name_on_entry = setlocale(LC_NUMERIC, NULL);
if ( strNE(locale_name_on_entry, "C")
&& strNE(locale_name_on_entry, "POSIX"))
{
/* the setlocale() call might free or overwrite the name */
locale_name_on_entry = savepv(locale_name_on_entry);
setlocale(LC_NUMERIC, "C");
}
else { /* This value indicates to the restore code that we
didn't change the locale */
locale_name_on_entry = NULL;
}
}
else if (locale_obj_on_entry == PL_underlying_numeric_obj) {
/* Here, the locale appears to have been changed to use the
* program's underlying locale. Just use our mechanisms to
* switch back to C. It might be possible for this pointer to
* actually refer to something else if it got released and
* reused somehow. But it doesn't matter, our mechanisms will
* work even so */
STORE_LC_NUMERIC_SET_STANDARD();
}
else if (locale_obj_on_entry != PL_C_locale_obj) {
/* The C object should be unchanged during a program's
* execution, so it should be safe to assume it means what it
* says, so if we are in it, no locale change is required.
* Otherwise, simply use the thread-safe operation. */
uselocale(PL_C_locale_obj);
}

# endif
/* Prevent recursed calls from trying to change back */
LOCK_LC_NUMERIC_STANDARD();
Expand Down Expand Up @@ -719,19 +680,7 @@ Perl_upg_version(pTHX_ SV *ver, bool qv)

LC_NUMERIC_UNLOCK; /* End critical section */
# else

if (locale_name_on_entry) {
setlocale(LC_NUMERIC, locale_name_on_entry);
Safefree(locale_name_on_entry);
LC_NUMERIC_UNLOCK;
}
else if (locale_obj_on_entry == PL_underlying_numeric_obj) {
RESTORE_LC_NUMERIC();
}
else if (locale_obj_on_entry != PL_C_locale_obj) {
uselocale(locale_obj_on_entry);
}

uselocale(locale_obj_on_entry);
# endif

}
Expand Down

0 comments on commit ae03410

Please sign in to comment.