This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix up LC_NUMERIC wrap macros
authorKarl Williamson <khw@cpan.org>
Mon, 2 Jun 2014 01:40:12 +0000 (19:40 -0600)
committerKarl Williamson <khw@cpan.org>
Thu, 5 Jun 2014 17:23:00 +0000 (11:23 -0600)
perl.h has some macros used to manipulate the locale exposed for the
category LC_NUMERIC.  These are currently undocumented, but will need to
be documented as the development of 5.21 progresses.  This fixes these
up in several ways:

The tests for if we are in the correct state are made into macros.  This
is in preparation for the next commit, which will make one of them more
complicated, and so that complication will only have to be in one place.

The variable declared by them is renamed to be preceded by an
underscore.  It is dangerous practice to have a name used in a macro, as
it could conflict with a name used by outside code.  This alleviates it
somewhat by making it even less likely to conflict.  This will have to
be revisited when some of these macros are made part of the public API.

The tests to see if things need to change are reversed.  Previously we
said we need to change to standard, for example, if the variable for
'local' is set.  But both can be true at the same time if the underlying
locale is C.  In this case, we only need to change if we aren't in
standard.  Whether that is also local is irrelevant.

locale.c
perl.h

index efd46fd..3004dce 100644 (file)
--- a/locale.c
+++ b/locale.c
@@ -201,7 +201,7 @@ Perl_set_numeric_standard(pTHX)
      * should use the macros like SET_NUMERIC_STANDARD() in perl.h instead of
      * calling this directly. */
 
-    if (! PL_numeric_standard) {
+    if (_NOT_IN_NUMERIC_STANDARD) {
        setlocale(LC_NUMERIC, "C");
        PL_numeric_standard = TRUE;
        PL_numeric_local = FALSE;
@@ -223,7 +223,7 @@ Perl_set_numeric_local(pTHX)
      * already there.  Probably should use the macros like SET_NUMERIC_LOCAL()
      * in perl.h instead of calling this directly. */
 
-    if (! PL_numeric_local) {
+    if (_NOT_IN_NUMERIC_LOCAL) {
        setlocale(LC_NUMERIC, PL_numeric_name);
        PL_numeric_standard = FALSE;
        PL_numeric_local = TRUE;
diff --git a/perl.h b/perl.h
index 140569e..970a25f 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -5335,18 +5335,21 @@ typedef struct am_table_short AMTS;
  * RESTORE_LC_NUMERIC() in all cases restores the locale to what it was before
  * these were called */
 
+#define _NOT_IN_NUMERIC_STANDARD (! PL_numeric_standard)
+#define _NOT_IN_NUMERIC_LOCAL    (! PL_numeric_local)
+
 #define DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED                       \
     void (*_restore_LC_NUMERIC_function)(pTHX) = NULL;
 
 #define STORE_LC_NUMERIC_SET_TO_NEEDED()                                     \
     if (IN_SOME_LOCALE_FORM) {                                               \
-        if (! PL_numeric_local) {                                            \
-            SET_NUMERIC_LOCAL();                                             \
+        if (_NOT_IN_NUMERIC_LOCAL) {                                         \
+            set_numeric_local();                                             \
             _restore_LC_NUMERIC_function = &Perl_set_numeric_standard;       \
         }                                                                    \
     }                                                                        \
     else {                                                                   \
-        if (! PL_numeric_standard) {                                         \
+        if (_NOT_IN_NUMERIC_STANDARD) {                                      \
             SET_NUMERIC_STANDARD();                                          \
             _restore_LC_NUMERIC_function = &Perl_set_numeric_local;          \
         }                                                                    \
@@ -5364,35 +5367,37 @@ typedef struct am_table_short AMTS;
 /* The next two macros set unconditionally.  These should be rarely used, and
  * only after being sure that this is what is needed */
 #define SET_NUMERIC_STANDARD()                                              \
-       STMT_START { if (! PL_numeric_standard) set_numeric_standard();     \
+       STMT_START { if (_NOT_IN_NUMERIC_STANDARD) set_numeric_standard();  \
                                                                  } STMT_END
 
 #define SET_NUMERIC_LOCAL()                                                 \
-       STMT_START { if (! PL_numeric_local) set_numeric_local(); } STMT_END
+       STMT_START { if (_NOT_IN_NUMERIC_LOCAL)                             \
+                                            set_numeric_local(); } STMT_END
 
 /* The rest of these LC_NUMERIC macros toggle to one or the other state, with
  * the RESTORE_foo ones called to switch back, but only if need be */
-#define STORE_NUMERIC_LOCAL_SET_STANDARD() \
-       bool was_local = PL_numeric_local; \
-       if (was_local) SET_NUMERIC_STANDARD();
+#define STORE_NUMERIC_LOCAL_SET_STANDARD()          \
+       bool _was_local = _NOT_IN_NUMERIC_STANDARD; \
+       if (_was_local) set_numeric_standard();
 
 /* Doesn't change to underlying locale unless within the scope of some form of
  * 'use locale'.  This is the usual desired behavior. */
-#define STORE_NUMERIC_STANDARD_SET_LOCAL() \
-       bool was_standard = PL_numeric_standard && IN_SOME_LOCALE_FORM; \
-       if (was_standard) SET_NUMERIC_LOCAL();
+#define STORE_NUMERIC_STANDARD_SET_LOCAL()              \
+       bool _was_standard = _NOT_IN_NUMERIC_LOCAL      \
+                            && IN_LC(LC_NUMERIC);       \
+       if (_was_standard) set_numeric_local();
 
 /* Rarely, we want to change to the underlying locale even outside of 'use
  * locale'.  This is principally in the POSIX:: functions */
-#define STORE_NUMERIC_STANDARD_FORCE_LOCAL() \
-       bool was_standard = PL_numeric_standard; \
-       if (was_standard) SET_NUMERIC_LOCAL();
+#define STORE_NUMERIC_STANDARD_FORCE_LOCAL()            \
+       bool _was_standard = _NOT_IN_NUMERIC_LOCAL;     \
+       if (_was_standard) set_numeric_local();
 
 #define RESTORE_NUMERIC_LOCAL() \
-       if (was_local) SET_NUMERIC_LOCAL();
+       if (_was_local) set_numeric_local();
 
 #define RESTORE_NUMERIC_STANDARD() \
-       if (was_standard) SET_NUMERIC_STANDARD();
+       if (_was_standard) SET_NUMERIC_STANDARD();
 
 #define Atof                           my_atof