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 Feb 2, 2023
1 parent fc5988c commit 1d9e7d1
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 59 deletions.
2 changes: 1 addition & 1 deletion t/porting/customized.dat
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ libnet cpan/libnet/lib/Net/POP3.pm 55a74121d7e6a122f63a12cec945777f6b8aa80b
libnet cpan/libnet/lib/Net/SMTP.pm 33efbd55e75486fe8201f9c63cf3f0704310a7b6
libnet cpan/libnet/lib/Net/Time.pm 3c86cd4d4db9ae207070d2e54f4d523b9ad58230
version cpan/version/lib/version.pm a963b513cf812bd7f4d28b3422efd9904e70a34c
version vutil.c 88855f7eb6ce443f57565d287ff2a0bbcd443bd2
version vutil.c 0c2a989d41de7e398b8ca745f4e0fe8714894694
65 changes: 7 additions & 58 deletions vutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,11 +626,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 @@ -647,49 +651,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 @@ -717,19 +678,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);
}

# endif

}
Expand Down

0 comments on commit 1d9e7d1

Please sign in to comment.