+
+#if PERL_VERSION_GE(5,19,0)
+ if (SvPOK(ver)) {
+ /* dualvar? */
+ goto VER_PV;
+ }
+#endif
+#ifdef USE_LOCALE_NUMERIC
+
+ {
+ /* This may or may not be called from code that has switched
+ * locales without letting perl know, therefore we have to find it
+ * from first principals. See [perl #121930]. */
+
+ /* In windows, or not threaded, or not thread-safe, if it isn't C,
+ * set it to C. */
+
+# ifndef USE_POSIX_2008_LOCALE
+
+ const char * locale_name_on_entry;
+
+ LC_NUMERIC_LOCK(0); /* Start critical section */
+
+ locale_name_on_entry = setlocale(LC_NUMERIC, NULL);
+ if ( strNE(locale_name_on_entry, "C")
+ && strNE(locale_name_on_entry, "POSIX"))
+ {
+ /* the setlocale() call might free or overwrite the name */
+ locale_name_on_entry = savepv(locale_name_on_entry);
+ setlocale(LC_NUMERIC, "C");
+ }
+ else { /* This value indicates to the restore code that we didn't
+ change the locale */
+ locale_name_on_entry = NULL;
+ }
+
+# else
+
+ const locale_t locale_obj_on_entry = uselocale((locale_t) 0);
+ const char * locale_name_on_entry = NULL;
+ DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
+
+ if (locale_obj_on_entry == LC_GLOBAL_LOCALE) {
+
+ /* in the global locale, we can call system setlocale and if it
+ * isn't C, set it to C. */
+ LC_NUMERIC_LOCK(0);
+
+ locale_name_on_entry = setlocale(LC_NUMERIC, NULL);
+ if ( strNE(locale_name_on_entry, "C")
+ && strNE(locale_name_on_entry, "POSIX"))
+ {
+ /* the setlocale() call might free or overwrite the name */
+ locale_name_on_entry = savepv(locale_name_on_entry);
+ setlocale(LC_NUMERIC, "C");
+ }
+ else { /* This value indicates to the restore code that we
+ didn't change the locale */
+ locale_name_on_entry = NULL;
+ }
+ }
+ else if (locale_obj_on_entry == PL_underlying_numeric_obj) {
+ /* Here, the locale appears to have been changed to use the
+ * program's underlying locale. Just use our mechanisms to
+ * switch back to C. It might be possible for this pointer to
+ * actually refer to something else if it got released and
+ * reused somehow. But it doesn't matter, our mechanisms will
+ * work even so */
+ STORE_LC_NUMERIC_SET_STANDARD();
+ }
+ else if (locale_obj_on_entry != PL_C_locale_obj) {
+ /* The C object should be unchanged during a program's
+ * execution, so it should be safe to assume it means what it
+ * says, so if we are in it, no locale change is required.
+ * Otherwise, simply use the thread-safe operation. */
+ uselocale(PL_C_locale_obj);
+ }
+
+# endif
+
+ /* Prevent recursed calls from trying to change back */
+ LOCK_LC_NUMERIC_STANDARD();
+
+#endif
+