Skip to content

Commit

Permalink
Add toggle_locale() fcns
Browse files Browse the repository at this point in the history
These are designed to temporarily switch the locale for a cateogry
around some operation that needs it to be different than the current
one.  They will be used in the next commit.

These will eventually replace the more unwieldy
_is_cur_LC_category_utf8() function, which toggles as a side effect
  • Loading branch information
khwilliamson committed Aug 10, 2022
1 parent 7f54a18 commit b7f3ba2
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 0 deletions.
6 changes: 6 additions & 0 deletions embed.fnc
Expand Up @@ -3328,6 +3328,12 @@ Sr |void |setlocale_failure_panic_i|const unsigned int cat_index \
|NN const char * failed \
|const line_t caller_0_line \
|const line_t caller_1_line
So |const char *|toggle_locale_i|const unsigned switch_cat_index \
|NN const char * new_locale \
|const line_t caller_line
So |void |restore_toggled_locale_i|const unsigned cat_index \
|NULLOK const char * original_locale \
|const line_t caller_line
# if defined(USE_POSIX_2008_LOCALE)
S |const char*|emulate_setlocale_i|const unsigned int index \
|NULLOK const char* new_locale \
Expand Down
97 changes: 97 additions & 0 deletions locale.c
Expand Up @@ -202,6 +202,14 @@ STATIC_ASSERT_DECL(STRLENs(UTF8NESS_PREFIX) == 1);
locale, result)
# endif

# define toggle_locale_i(index, locale) \
S_toggle_locale_i(aTHX_ index, locale, __LINE__)
# define toggle_locale_c(cat, locale) toggle_locale_i(cat##_INDEX_, locale)
# define restore_toggled_locale_i(index, locale) \
S_restore_toggled_locale_i(aTHX_ index, locale, __LINE__)
# define restore_toggled_locale_c(cat, locale) \
restore_toggled_locale_i(cat##_INDEX_, locale)

/* Two parallel arrays indexed by our mapping of category numbers into small
* non-negative indexes; first the locale categories Perl uses on this system,
* used to do the inverse mapping. The second array is their names. These
Expand Down Expand Up @@ -4952,6 +4960,95 @@ S_print_bytes_for_locale(pTHX_

# endif /* #ifdef DEBUGGING */

STATIC const char *
S_toggle_locale_i(pTHX_ const unsigned cat_index,
const char * new_locale,
const line_t caller_line)
{
/* Changes the locale for the category specified by 'index' to 'new_locale,
* if they aren't already the same.
*
* Returns a copy of the name of the original locale for 'cat_index'
* so can be switched back to with the companion function
* restore_toggled_locale_i(), (NULL if no restoral is necessary.) */

const char * locale_to_restore_to = NULL;

PERL_ARGS_ASSERT_TOGGLE_LOCALE_I;
assert(cat_index <= NOMINAL_LC_ALL_INDEX);

/* Find the original locale of the category we may need to change, so that
* it can be restored to later */

locale_to_restore_to = querylocale_i(cat_index);

DEBUG_Lv(PerlIO_printf(Perl_debug_log,
"(%" LINE_Tf "): toggle_locale_i: index=%d(%s), wanted=%s,"
" actual=%s\n",
caller_line, cat_index, category_names[cat_index],
new_locale, locale_to_restore_to));

if (! locale_to_restore_to) {
locale_panic_(Perl_form(aTHX_ "Could not find current %s locale, errno=%d",
category_names[cat_index], errno));
}

/* If the locales are the same, there's nothing to do */
if (strEQ(locale_to_restore_to, new_locale)) {
DEBUG_Lv(PerlIO_printf(Perl_debug_log,
"(%d): %s locale unchanged as %s\n",
caller_line, category_names[cat_index],
new_locale));

return NULL;
}

/* Finally, change the locale to the new one */
void_setlocale_i(cat_index, new_locale);

DEBUG_Lv(PerlIO_printf(Perl_debug_log, "(%" LINE_Tf "): %s locale switched to %s\n",
caller_line, category_names[cat_index], new_locale));

return locale_to_restore_to;

#ifndef DEBUGGING
PERL_UNUSED_ARG(caller_line);
#endif

}

STATIC void
S_restore_toggled_locale_i(pTHX_ const unsigned int cat_index,
const char * restore_locale,
const line_t caller_line)
{
/* Restores the locale for LC_category corresponding to cat_indes to
* 'restore_locale' (which is a copy that will be freed by this function),
* or do nothing if the latter parameter is NULL */

PERL_ARGS_ASSERT_RESTORE_TOGGLED_LOCALE_I;
assert(cat_index <= NOMINAL_LC_ALL_INDEX);

if (restore_locale == NULL) {
DEBUG_Lv(PerlIO_printf(Perl_debug_log,
"(%" LINE_Tf "): No need to restore %s\n",
caller_line, category_names[cat_index]));
return;
}

DEBUG_Lv(PerlIO_printf(Perl_debug_log,
"(%" LINE_Tf "): %s restoring locale to %s\n",
caller_line, category_names[cat_index],
restore_locale));

void_setlocale_i(cat_index, restore_locale);

#ifndef DEBUGGING
PERL_UNUSED_ARG(caller_line);
#endif

}

STATIC const char *
S_switch_category_locale_to_template(pTHX_ const int switch_category,
const int template_category,
Expand Down
5 changes: 5 additions & 0 deletions proto.h
Expand Up @@ -5646,6 +5646,8 @@ STATIC void S_new_numeric(pTHX_ const char* newnum);
#define PERL_ARGS_ASSERT_NEW_NUMERIC
STATIC void S_restore_switched_locale(pTHX_ const int category, const char * const original_locale);
#define PERL_ARGS_ASSERT_RESTORE_SWITCHED_LOCALE
STATIC void S_restore_toggled_locale_i(pTHX_ const unsigned cat_index, const char * original_locale, const line_t caller_line);
#define PERL_ARGS_ASSERT_RESTORE_TOGGLED_LOCALE_I
STATIC const char * S_save_to_buffer(const char * string, const char **buf, Size_t *buf_size);
#define PERL_ARGS_ASSERT_SAVE_TO_BUFFER
STATIC void S_set_numeric_radix(pTHX_ const bool use_locale);
Expand All @@ -5659,6 +5661,9 @@ STATIC const char* S_stdize_locale(pTHX_ const int category, const char* input_l
#define PERL_ARGS_ASSERT_STDIZE_LOCALE
STATIC const char* S_switch_category_locale_to_template(pTHX_ const int switch_category, const int template_category, const char * template_locale);
#define PERL_ARGS_ASSERT_SWITCH_CATEGORY_LOCALE_TO_TEMPLATE
STATIC const char * S_toggle_locale_i(pTHX_ const unsigned switch_cat_index, const char * new_locale, const line_t caller_line);
#define PERL_ARGS_ASSERT_TOGGLE_LOCALE_I \
assert(new_locale)
# if defined(USE_POSIX_2008_LOCALE)
STATIC const char* S_emulate_setlocale_i(pTHX_ const unsigned int index, const char* new_locale, const int recalc_LC_ALL, const line_t line);
#define PERL_ARGS_ASSERT_EMULATE_SETLOCALE_I
Expand Down

0 comments on commit b7f3ba2

Please sign in to comment.