Skip to content

Commit

Permalink
Fix querying locale without LC_NUMERIC on platform
Browse files Browse the repository at this point in the history
This fixes GH #19890.

This cleans up querying the current locale, broken by 996e6b9 on
platforms without LC_NUMERIC(*).

That commit was written before we required C99, and being able to move
declarations to not be at the beginning of a block made me realize that
things could be simplified by a bit of refactoring, which this commit
does.

(*): Lack of LC_NUMERIC can be simulated by using

  './Configure -Accflags="-DNO_LOCALE_NUMERIC'
  • Loading branch information
khwilliamson committed Jun 27, 2022
1 parent 2c10e97 commit 6a7aca8
Showing 1 changed file with 27 additions and 15 deletions.
42 changes: 27 additions & 15 deletions locale.c
Expand Up @@ -2257,12 +2257,12 @@ Perl_setlocale(const int category, const char * locale)
/* A NULL locale means only query what the current one is. */
if (locale == NULL) {

# ifdef USE_LOCALE_NUMERIC
# ifdef LC_ALL
# ifndef USE_LOCALE_NUMERIC

bool toggled = FALSE;
/* Without LC_NUMERIC, it's trivial; we just return the value */
return querylocale_r(category);

# endif
# else

/* We have the LC_NUMERIC name saved, because we are normally switched
* into the C locale (or equivalent) for it. */
Expand All @@ -2273,34 +2273,46 @@ Perl_setlocale(const int category, const char * locale)
return PL_numeric_name;
}

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

/* Without LC_ALL, just return the value */
return querylocale_r(category);

# else

/* Here, LC_ALL is available on this platform. It's the one
* complicating category (because it can contain a toggled LC_NUMERIC
* value), for all the remaining ones (we took care of LC_NUMERIC
* above), just return the value */
if (category != LC_ALL) {
return querylocale_r(category);
}

bool toggled = FALSE;

/* 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 && ! PL_numeric_underlying) {
if (! PL_numeric_underlying) {
set_numeric_underlying();
toggled = TRUE;
}

# endif

retval = querylocale_r(category);

# ifdef LC_ALL
retval = querylocale_c(LC_ALL);

if (toggled) {

/* This toggling back could destroy 'retval' */
retval = save_to_buffer(retval,
&PL_setlocale_buf, &PL_setlocale_bufsize, 0);
set_numeric_standard();
}

# endif
}

return retval;

# endif /* Has LC_ALL */
# endif /* Has LC_NUMERIC */

} /* End of querying the current locale */

cat_index = get_category_index(category, NULL);
Expand Down

0 comments on commit 6a7aca8

Please sign in to comment.