Skip to content

Commit

Permalink
Perl_setlocale(): Same code for all param2 == NULL
Browse files Browse the repository at this point in the history
Calling Perl_setlocale() with a NULL 2nd parameter returns the current
locale, rather than changing it.  Previously LC_NUMERIC and LC_ALL were
treated specially; other categories were lumped in with the code that
changes the locale.

Changing some categories involves a non-trivial amount of work.  This
commit avoids that by moving all queries to the same 'if' branch.
LC_NUMERIC and LC_ALL still have to be treated specially, but now it's
all within the same outer 'if', and the unnecessarily executing code
for when the locale changes is avoided.
  • Loading branch information
khwilliamson committed May 9, 2021
1 parent 15ff324 commit 37f30de
Showing 1 changed file with 26 additions and 22 deletions.
48 changes: 26 additions & 22 deletions locale.c
Expand Up @@ -2233,16 +2233,19 @@ Perl_setlocale(const int category, const char * locale)
unsigned int cat_index;
dSAVEDERRNO;
dTHX;

/* A NULL locale means only query what the current one is. */
if (locale == NULL) {

# ifdef USE_LOCALE_NUMERIC
# ifdef LC_ALL

DECLARATION_FOR_LC_NUMERIC_MANIPULATION;

#ifdef USE_LOCALE_NUMERIC
# endif

/* A NULL locale means only query what the current one is. We have the
* LC_NUMERIC name saved, because we are normally switched into the C
* (or equivalent) locale for it. For an LC_ALL query, switch back to get
* the correct results. All other categories don't require special
* handling */
if (locale == NULL) {
/* We have the LC_NUMERIC name saved, because we are normally switched
* into the C locale (or equivalent) for it. */
if (category == LC_NUMERIC) {

/* We don't have to copy this return value, as it is a per-thread
Expand All @@ -2252,29 +2255,35 @@ Perl_setlocale(const int category, const char * locale)

# ifdef LC_ALL

else if (category == LC_ALL) {
/* For an LC_ALL query, switch back to the underlying numeric locale
* (if we aren't there already) so as to get the correct results. Our
* records for all the other categories are valid without switching */
if (category == LC_ALL) {
STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
}

# endif
# endif /* End of has LC_NUMERIC */

retval = save_to_buffer(querylocale_r(category),
&PL_setlocale_buf, &PL_setlocale_bufsize, 0);

# if defined(USE_LOCALE_NUMERIC) && defined(LC_ALL)

if (category == LC_ALL) {
RESTORE_LC_NUMERIC();
}

#endif
# endif

return retval;
} /* End of querying the current locale */

cat_index = get_category_index(category, NULL);
retval = save_to_buffer(setlocale_i(cat_index, locale),
&PL_setlocale_buf, &PL_setlocale_bufsize, 0);
SAVE_ERRNO;

#if defined(USE_LOCALE_NUMERIC) && defined(LC_ALL)

if (locale == NULL && category == LC_ALL) {
RESTORE_LC_NUMERIC();
}

#endif

DEBUG_L(PerlIO_printf(Perl_debug_log,
"%s:%d: %s\n", __FILE__, __LINE__,
setlocale_debug_string_r(category, locale, retval)));
Expand All @@ -2285,11 +2294,6 @@ Perl_setlocale(const int category, const char * locale)
return NULL;
}

/* If locale == NULL, we are just querying the state */
if (locale == NULL) {
return retval;
}

/* Now that have changed locales, we have to update our records to
* correspond. Only certain categories have extra work to update. */
if (update_functions[cat_index]) {
Expand Down

0 comments on commit 37f30de

Please sign in to comment.