Skip to content

Commit

Permalink
perl.h: Add DISABLE_LC_NUMERIC_CHANGES macro
Browse files Browse the repository at this point in the history
This is for code that needs to keep other code from changing LC_NUMERIC
out from under it, but avoids the knowledge of PL_numeric_standard,
which is used when perl controls the locale handling.

This is designed for 'version' (vutil.c) to use, because it has to
operate seamlessly in the mode where perl controls the handling, and
when it doesn't, even if it doesn't know it doesn't.
  • Loading branch information
khwilliamson committed Jun 3, 2023
1 parent f93d81f commit 5092839
Showing 1 changed file with 22 additions and 5 deletions.
27 changes: 22 additions & 5 deletions perl.h
Expand Up @@ -7795,18 +7795,22 @@ cannot have changed since the precalculation.
} \
} STMT_END

/* Lock/unlock to the C locale until unlock is called. This needs to be
* recursively callable. [perl #128207] */
# define LOCK_LC_NUMERIC_STANDARD() \
/* Lock/unlock changes to LC_NUMERIC. This needs to be recursively callable.
* The highest level caller is responsible for making sure that LC_NUMERIC is
* set to a locale with a dot radix character. These deliberately don't check
* for the internal state being so, as they can be called from code that is not
* party to the internal conventions, namely 'version' (vutil.c).
* PL_numeric_standard changing doesn't affect anything about what locale is in
* effect, etc. [perl #128207] */
# define DISABLE_LC_NUMERIC_CHANGES() \
STMT_START { \
DEBUG_Lv(PerlIO_printf(Perl_debug_log, \
"%s: %d: lc_numeric_standard now locked to depth %d\n", \
__FILE__, __LINE__, PL_numeric_standard)); \
__ASSERT_(PL_numeric_standard) \
PL_numeric_standard++; \
} STMT_END

# define UNLOCK_LC_NUMERIC_STANDARD() \
# define REENABLE_LC_NUMERIC_CHANGES() \
STMT_START { \
if (PL_numeric_standard > 1) { \
PL_numeric_standard--; \
Expand All @@ -7824,6 +7828,17 @@ cannot have changed since the precalculation.
PL_numeric_standard););\
} STMT_END

/* Essentially synonyms for the above. The LOCK asserts at the top level that
* we are in a locale equivalent to C. By including the top level, this can be
* recursively called from chains which include DISABLE_LC_NUMERIC_CHANGES().
* */
# define LOCK_LC_NUMERIC_STANDARD() \
STMT_START { \
assert(PL_numeric_standard > 0 || PL_numeric_standard); \
DISABLE_LC_NUMERIC_CHANGES(); \
} STMT_END
# define UNLOCK_LC_NUMERIC_STANDARD() REENABLE_LC_NUMERIC_CHANGES()

# define WITH_LC_NUMERIC_SET_TO_NEEDED_IN(in_lc_numeric, block) \
STMT_START { \
DECLARATION_FOR_LC_NUMERIC_MANIPULATION; \
Expand All @@ -7848,6 +7863,8 @@ cannot have changed since the precalculation.
# define RESTORE_LC_NUMERIC()
# define LOCK_LC_NUMERIC_STANDARD()
# define UNLOCK_LC_NUMERIC_STANDARD()
# define DISABLE_LC_NUMERIC_CHANGES()
# define REENABLE_LC_NUMERIC_CHANGES()
# define WITH_LC_NUMERIC_SET_TO_NEEDED_IN(in_lc_numeric, block) \
STMT_START { block; } STMT_END
# define WITH_LC_NUMERIC_SET_TO_NEEDED(block) \
Expand Down

0 comments on commit 5092839

Please sign in to comment.