Skip to content

Commit

Permalink
locale.c: Use a function table to simplify code
Browse files Browse the repository at this point in the history
Some locale categories require extra steps when they are changed.  This
moves that logic to a table, which gets rid of some code
  • Loading branch information
khwilliamson committed Apr 30, 2021
1 parent 0ed8940 commit d50bf9b
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 76 deletions.
1 change: 1 addition & 0 deletions embed.fnc
Expand Up @@ -3239,6 +3239,7 @@ Sr |void |setlocale_failure_panic_i|const unsigned int cat_index \
|const line_t caller_1_line
S |void |set_numeric_radix|const bool use_locale
S |void |new_numeric |NULLOK const char* newnum
S |void |new_LC_ALL |NULLOK const char* unused
# ifdef USE_POSIX_2008_LOCALE
S |const char*|emulate_setlocale_i|const unsigned int index \
|NULLOK const char* locale
Expand Down
1 change: 1 addition & 0 deletions embed.h
Expand Up @@ -1693,6 +1693,7 @@
# if defined(USE_LOCALE)
#define category_name S_category_name
#define get_category_index S_get_category_index
#define new_LC_ALL(a) S_new_LC_ALL(aTHX_ a)
#define new_collate(a) S_new_collate(aTHX_ a)
#define new_ctype(a) S_new_ctype(aTHX_ a)
#define new_numeric(a) S_new_numeric(aTHX_ a)
Expand Down
149 changes: 73 additions & 76 deletions locale.c
Expand Up @@ -281,6 +281,56 @@ STATIC const char * const category_names[] = {
NULL
};

/* A few categories require additional setup when they are changed. This table
* points to the functions that do that setup */
STATIC void (*update_functions[]) (pTHX_ const char *) = {
# ifdef USE_LOCALE_NUMERIC
S_new_numeric,
# endif
# ifdef USE_LOCALE_CTYPE
S_new_ctype,
# endif
# ifdef USE_LOCALE_COLLATE
S_new_collate,
# endif
# ifdef USE_LOCALE_TIME
NULL,
# endif
# ifdef USE_LOCALE_MESSAGES
NULL,
# endif
# ifdef USE_LOCALE_MONETARY
NULL,
# endif
# ifdef USE_LOCALE_ADDRESS
NULL,
# endif
# ifdef USE_LOCALE_IDENTIFICATION
NULL,
# endif
# ifdef USE_LOCALE_MEASUREMENT
NULL,
# endif
# ifdef USE_LOCALE_PAPER
NULL,
# endif
# ifdef USE_LOCALE_TELEPHONE
NULL,
# endif
# ifdef USE_LOCALE_SYNTAX
NULL,
# endif
# ifdef USE_LOCALE_TOD
NULL,
# endif
/* No harm done to have this even without an LC_ALL */
S_new_LC_ALL,

/* Placeholder as a precaution if code fails to check the return of
* get_category_index(), which returns this element to indicate an error */
NULL
};

# ifdef LC_ALL

/* On systems with LC_ALL, it is kept in the highest index position. (-2
Expand Down Expand Up @@ -467,7 +517,7 @@ S_category_name(const int category)

# endif

/* A third array, parallel to the ones above to map from category to its
/* A fourth array, parallel to the ones above to map from category to its
* equivalent mask */
STATIC const int category_masks[] = {
# ifdef USE_LOCALE_NUMERIC
Expand Down Expand Up @@ -1735,6 +1785,22 @@ Perl__warn_problematic_locale()

}

STATIC void
S_new_LC_ALL(pTHX_ const char *unused)
{
unsigned int i;

/* LC_ALL updates all the things we care about. */

PERL_UNUSED_ARG(unused);

for (i = 0; i < NOMINAL_LC_ALL_INDEX; i++) {
if (update_functions[i]) {
update_functions[i](aTHX_ querylocale_i(i));
}
}
}

STATIC void
S_new_collate(pTHX_ const char *newcoll)
{
Expand Down Expand Up @@ -2164,7 +2230,7 @@ Perl_setlocale(const int category, const char * locale)
#else

const char * retval;
const char * newlocale;
unsigned int cat_index;
dSAVEDERRNO;
dTHX;
DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
Expand Down Expand Up @@ -2196,7 +2262,8 @@ Perl_setlocale(const int category, const char * locale)

#endif

retval = save_to_buffer(setlocale_r(category, 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;

Expand Down Expand Up @@ -2225,63 +2292,8 @@ Perl_setlocale(const int category, const char * locale)

/* Now that have changed locales, we have to update our records to
* correspond. Only certain categories have extra work to update. */

switch (category) {

#ifdef USE_LOCALE_CTYPE

case LC_CTYPE:
new_ctype(retval);
break;

#endif
#ifdef USE_LOCALE_COLLATE

case LC_COLLATE:
new_collate(retval);
break;

#endif
#ifdef USE_LOCALE_NUMERIC

case LC_NUMERIC:
new_numeric(retval);
break;

#endif
#ifdef LC_ALL

case LC_ALL:

/* LC_ALL updates all the things we care about. The values may not
* be the same as 'retval', as the locale "" may have set things
* individually */

# ifdef USE_LOCALE_CTYPE

newlocale = savepv(querylocale_c(LC_CTYPE));
new_ctype(newlocale);
Safefree(newlocale);

# endif /* USE_LOCALE_CTYPE */
# ifdef USE_LOCALE_COLLATE

newlocale = savepv(querylocale_c(LC_COLLATE));
new_collate(newlocale);
Safefree(newlocale);

# endif
# ifdef USE_LOCALE_NUMERIC

newlocale = savepv(querylocale_c(LC_NUMERIC));
new_numeric(newlocale);
Safefree(newlocale);

# endif /* USE_LOCALE_NUMERIC */
#endif /* LC_ALL */

default:
break;
if (update_functions[cat_index]) {
update_functions[cat_index](aTHX_ retval);
}

return retval;
Expand Down Expand Up @@ -3741,22 +3753,7 @@ Perl_init_i18nl10n(pTHX_ int printwarn)
} /* End of tried to fallback */

/* Done with finding the locales; update our records */

# ifdef USE_LOCALE_CTYPE

new_ctype(curlocales[LC_CTYPE_INDEX_]);

# endif
# ifdef USE_LOCALE_COLLATE

new_collate(curlocales[LC_COLLATE_INDEX_]);

# endif
# ifdef USE_LOCALE_NUMERIC

new_numeric(curlocales[LC_NUMERIC_INDEX_]);

# endif
new_LC_ALL(NULL);

for (i = 0; i < NOMINAL_LC_ALL_INDEX; i++) {

Expand Down
2 changes: 2 additions & 0 deletions proto.h
Expand Up @@ -5123,6 +5123,8 @@ STATIC const char* S_category_name(const int category);
#define PERL_ARGS_ASSERT_CATEGORY_NAME
STATIC unsigned int S_get_category_index(const int category, const char * locale);
#define PERL_ARGS_ASSERT_GET_CATEGORY_INDEX
STATIC void S_new_LC_ALL(pTHX_ const char* unused);
#define PERL_ARGS_ASSERT_NEW_LC_ALL
STATIC void S_new_collate(pTHX_ const char* newcoll);
#define PERL_ARGS_ASSERT_NEW_COLLATE
STATIC void S_new_ctype(pTHX_ const char* newctype);
Expand Down

0 comments on commit d50bf9b

Please sign in to comment.