summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Williamson <khw@cpan.org>2022-08-18 07:13:48 -0600
committerKarl Williamson <khw@cpan.org>2022-08-18 09:08:41 -0600
commit20be777ac8192a8b5d25010670ab9de16a143732 (patch)
tree12e3d5367eb4707050dafd650229979828784f9f
parentf14a9aff6e1a937b71ee9cc6b088b99df87b23df (diff)
downloadperl-20be777ac8192a8b5d25010670ab9de16a143732.tar.gz
locale.c: Change to use an enum parameter
These two functions take as input a parameter that is three-valued. Basically, the meanings are 'true', 'false', and 'special'. This changes them to use an enum instead, so that the compiler will detect if they are being called with an unanticipated value. The parameter names now become more self-documenting. Comments are added to better explain what 'special' means, and why it exists.
-rw-r--r--embed.fnc4
-rw-r--r--locale.c76
-rw-r--r--perl.h17
-rw-r--r--proto.h4
4 files changed, 62 insertions, 39 deletions
diff --git a/embed.fnc b/embed.fnc
index a8cea40cbc..cb42b4381c 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -3334,7 +3334,7 @@ Sr |void |setlocale_failure_panic_i|const unsigned int cat_index \
# if defined(USE_POSIX_2008_LOCALE)
S |const char*|emulate_setlocale_i|const unsigned int index \
|NULLOK const char* new_locale \
- |const int recalc_LC_ALL \
+ |const recalc_lc_all_t recalc_LC_ALL\
|const line_t line
S |const char*|my_querylocale_i|const unsigned int index
S |locale_t |use_curlocale_scratch
@@ -3347,7 +3347,7 @@ S |const char *|calculate_LC_ALL|const locale_t cur_obj
S |const char *|calculate_LC_ALL|NN const char ** individ_locales
S |const char*|update_PL_curlocales_i|const unsigned int index \
|NN const char * new_locale \
- |int recalc_LC_ALL
+ |recalc_lc_all_t recalc_LC_ALL
S |const char *|find_locale_from_environment|const unsigned int index
# endif
# endif
diff --git a/locale.c b/locale.c
index 9df192ec94..eecd545801 100644
--- a/locale.c
+++ b/locale.c
@@ -555,9 +555,9 @@ Perl_locale_panic(const char * msg,
# define emulate_setlocale_c(cat, locale, recalc_LC_ALL, line) \
emulate_setlocale_i(cat##_INDEX_, locale, recalc_LC_ALL, line)
- /* A wrapper for the macros below. TRUE => do recalculate LC_ALL */
+ /* A wrapper for the macros below. */
# define common_emulate_setlocale(i, locale) \
- emulate_setlocale_i(i, locale, TRUE, __LINE__)
+ emulate_setlocale_i(i, locale, YES_RECALC_LC_ALL, __LINE__)
# define setlocale_i(i, locale) common_emulate_setlocale(i, locale)
# define setlocale_c(cat, locale) setlocale_i(cat##_INDEX_, locale)
@@ -715,22 +715,13 @@ S_my_querylocale_i(pTHX_ const unsigned int index)
return retval;
}
-# define LOOPING -1 /* Special value for 'recalc_LC_ALL' parameter below */
-
# ifdef USE_PL_CURLOCALES
STATIC const char *
S_update_PL_curlocales_i(pTHX_
const unsigned int index,
const char * new_locale,
-
- /* 0 => skip recalculating LC_ALL;
- * 1 => do recalculate LC_ALL
- * LOOPING => this call is part of a loop that goes
- * through all categories by index-order.
- * Recalculate only on the final iteration,
- * after all values are known */
- int recalc_LC_ALL)
+ recalc_lc_all_t recalc_LC_ALL)
{
/* This is a helper function for emulate_setlocale_i(), mostly used to
* make that function easier to read. */
@@ -749,7 +740,7 @@ S_update_PL_curlocales_i(pTHX_
PL_curlocales[i] = savepv(new_locale);
}
- recalc_LC_ALL = TRUE;
+ recalc_LC_ALL = YES_RECALC_LC_ALL;
}
else {
@@ -757,12 +748,14 @@ S_update_PL_curlocales_i(pTHX_
Safefree(PL_curlocales[index]);
PL_curlocales[index] = savepv(new_locale);
- if (recalc_LC_ALL == LOOPING) {
- recalc_LC_ALL = (index == NOMINAL_LC_ALL_INDEX - 1);
+ if (recalc_LC_ALL == RECALCULATE_LC_ALL_ON_FINAL_INTERATION) {
+ recalc_LC_ALL = (index == NOMINAL_LC_ALL_INDEX - 1)
+ ? YES_RECALC_LC_ALL
+ : DONT_RECALC_LC_ALL;
}
}
- if (recalc_LC_ALL) { /* And recalculate LC_ALL */
+ if (recalc_LC_ALL == YES_RECALC_LC_ALL) {
Safefree(PL_curlocales[LC_ALL_INDEX_]);
PL_curlocales[LC_ALL_INDEX_] =
savepv(calculate_LC_ALL(PL_curlocales));
@@ -804,7 +797,7 @@ S_setlocale_from_aggregate_LC_ALL(pTHX_ const char * locale, const line_t line)
* all the individual categories to "C", and override the furnished
* ones below. FALSE => No need to recalculate LC_ALL, as this is a
* temporary state */
- if (! emulate_setlocale_c(LC_ALL, "C", FALSE, line)) {
+ if (! emulate_setlocale_c(LC_ALL, "C", DONT_RECALC_LC_ALL, line)) {
setlocale_failure_panic_c(LC_ALL, locale_on_entry,
"C", __LINE__, line);
NOT_REACHED; /* NOTREACHED */
@@ -862,10 +855,13 @@ S_setlocale_from_aggregate_LC_ALL(pTHX_ const char * locale, const line_t line)
/* And do the change. FALSE => Don't recalculate LC_ALL; we'll do
* it ourselves after the loop */
- if (! emulate_setlocale_i(i, individ_locale, FALSE, line)) {
+ if (! emulate_setlocale_i(i, individ_locale,
+ DONT_RECALC_LC_ALL, line))
+ {
/* But if we have to back out, do fix up LC_ALL */
- if (! emulate_setlocale_c(LC_ALL, locale_on_entry, TRUE, line))
+ if (! emulate_setlocale_c(LC_ALL, locale_on_entry,
+ YES_RECALC_LC_ALL, line))
{
Safefree(locale_on_entry);
setlocale_failure_panic_i(i, individ_locale,
@@ -991,10 +987,15 @@ S_find_locale_from_environment(pTHX_ const unsigned int index)
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)
+
+ /* Our internal index of the 'category' setlocale is
+ called with */
+ const unsigned int index,
+
+ const char * new_locale, /* The locale to set the category to */
+ const recalc_lc_all_t recalc_LC_ALL, /* Explained below */
+ const line_t line /* Called from this line number */
+ )
{
PERL_ARGS_ASSERT_EMULATE_SETLOCALE_I;
assert(index <= NOMINAL_LC_ALL_INDEX);
@@ -1010,16 +1011,19 @@ S_emulate_setlocale_i(pTHX_
* By doing this, most locale-sensitive functions become thread-safe. The
* exceptions are mostly those that return a pointer to static memory.
*
- * This function takes our internal index of the 'category' setlocale is
- * called with, and the 'new_locale' to set the category to. It uses the
- * index to find the category mask that the POSIX 2008 functions use.
+ * This function may be called in a tight loop that iterates over all
+ * categories. Because LC_ALL is not a "real" category, but merely the sum
+ * of all the other ones, such loops don't include LC_ALL. On systems that
+ * have querylocale() or similar, the current LC_ALL value is immediately
+ * retrievable; on systems lacking that feature, we have to keep track of
+ * LC_ALL ourselves. We could do that on each iteration, only to throw it
+ * away on the next, but the calculation is more than a trivial amount of
+ * work. Instead, the 'recalc_LC_ALL' parameter is set to
+ * RECALCULATE_LC_ALL_ON_FINAL_INTERATION to only do the calculation once.
+ * This function calls itself recursively in such a loop.
*
- * The function can be called recursively on all the individual categories,
- * when the outer call is for LC_ALL. It would be unnecessary work to
- * recalculate LC_ALL in the middle of all this; so the 'recalc_LC_ALL'
- * parameter is set to LOOPING in this circumstance, to indicate to
- * recalculate only on the final category; 0 to indicate to not recalculate
- * at all; and 1 to indicate to do so unconditionally */
+ * When not in such a loop, the parameter is set to the other enum values
+ * DONT_RECALC_LC_ALL or YES_RECALC_LC_ALL. */
int mask = category_masks[index];
const locale_t entry_obj = uselocale((locale_t) 0);
@@ -1179,11 +1183,11 @@ S_emulate_setlocale_i(pTHX_
* here. khw isn't sure if this prevents some issues or not,
* but tis is defensive coding. The system setlocale() returns
* the desired information. This will calculate LC_ALL's entry
- * on the final iteration */
+ * only on the final iteration */
for (PERL_UINT_FAST8_T i = 0; i < NOMINAL_LC_ALL_INDEX; i++) {
update_PL_curlocales_i(i,
porcelain_setlocale(categories[i], NULL),
- LOOPING);
+ RECALCULATE_LC_ALL_ON_FINAL_INTERATION);
}
}
# endif
@@ -4011,7 +4015,9 @@ Perl_init_i18nl10n(pTHX_ int printwarn)
* them now, calculating LC_ALL only on the final go round, when all have
* been set. */
for (i = 0; i < NOMINAL_LC_ALL_INDEX; i++) {
- (void) emulate_setlocale_i(i, curlocales[i], LOOPING, __LINE__);
+ (void) emulate_setlocale_i(i, curlocales[i],
+ RECALCULATE_LC_ALL_ON_FINAL_INTERATION,
+ __LINE__);
}
# endif
diff --git a/perl.h b/perl.h
index 7fbec1c8c0..964db38924 100644
--- a/perl.h
+++ b/perl.h
@@ -1352,6 +1352,23 @@ violations are fatal.
# endif
#endif
+#ifdef PERL_CORE
+
+/* Used in locale.c only, but defined here so that embed.fnc can generate
+ * the proper prototypes. */
+
+typedef enum {
+ DONT_RECALC_LC_ALL,
+ YES_RECALC_LC_ALL,
+
+ /* Used in tight loops through all sub-categories, where LC_ALL won't be
+ * fully known until all subcategories are handled. */
+ RECALCULATE_LC_ALL_ON_FINAL_INTERATION
+} recalc_lc_all_t;
+
+#endif
+
+
#include <setjmp.h>
#ifdef I_SYS_PARAM
diff --git a/proto.h b/proto.h
index 8e9943d1eb..b0e9072a28 100644
--- a/proto.h
+++ b/proto.h
@@ -4692,7 +4692,7 @@ STATIC const char * S_calculate_LC_ALL(pTHX_ const char ** individ_locales);
assert(individ_locales)
STATIC const char * S_find_locale_from_environment(pTHX_ const unsigned int index);
#define PERL_ARGS_ASSERT_FIND_LOCALE_FROM_ENVIRONMENT
-STATIC const char* S_update_PL_curlocales_i(pTHX_ const unsigned int index, const char * new_locale, int recalc_LC_ALL);
+STATIC const char* S_update_PL_curlocales_i(pTHX_ const unsigned int index, const char * new_locale, recalc_lc_all_t recalc_LC_ALL);
#define PERL_ARGS_ASSERT_UPDATE_PL_CURLOCALES_I \
assert(new_locale)
# endif
@@ -5648,7 +5648,7 @@ STATIC const char* S_stdize_locale(pTHX_ const int category, const char* input_l
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
# 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);
+STATIC const char* S_emulate_setlocale_i(pTHX_ const unsigned int index, const char* new_locale, const recalc_lc_all_t recalc_LC_ALL, const line_t line);
#define PERL_ARGS_ASSERT_EMULATE_SETLOCALE_I
STATIC const char* S_my_querylocale_i(pTHX_ const unsigned int index);
#define PERL_ARGS_ASSERT_MY_QUERYLOCALE_I