+#ifdef WIN32
+
+char *
+Perl_my_setlocale(pTHX_ int category, const char* locale)
+{
+ /* This, for Windows, emulates POSIX setlocale() behavior. There is no
+ * difference unless the input locale is "", which means on Windows to get
+ * the machine default, which is set via the computer's "Regional and
+ * Language Options" (or its current equivalent). In POSIX, it instead
+ * means to find the locale from the user's environment. This routine
+ * looks in the environment, and, if anything is found, uses that instead
+ * of going to the machine default. If there is no environment override,
+ * the machine default is used, as normal, by calling the real setlocale()
+ * with "". The POSIX behavior is to use the LC_ALL variable if set;
+ * otherwise to use the particular category's variable if set; otherwise to
+ * use the LANG variable. */
+
+ bool override_LC_ALL = 0;
+ char * result;
+
+ if (locale && strEQ(locale, "")) {
+# ifdef LC_ALL
+ locale = PerlEnv_getenv("LC_ALL");
+ if (! locale) {
+#endif
+ switch (category) {
+# ifdef LC_ALL
+ case LC_ALL:
+ override_LC_ALL = TRUE;
+ break; /* We already know its variable isn't set */
+# endif
+# ifdef USE_LOCALE_TIME
+ case LC_TIME:
+ locale = PerlEnv_getenv("LC_TIME");
+ break;
+# endif
+# ifdef USE_LOCALE_CTYPE
+ case LC_CTYPE:
+ locale = PerlEnv_getenv("LC_CTYPE");
+ break;
+# endif
+# ifdef USE_LOCALE_COLLATE
+ case LC_COLLATE:
+ locale = PerlEnv_getenv("LC_COLLATE");
+ break;
+# endif
+# ifdef USE_LOCALE_MONETARY
+ case LC_MONETARY:
+ locale = PerlEnv_getenv("LC_MONETARY");
+ break;
+# endif
+# ifdef USE_LOCALE_NUMERIC
+ case LC_NUMERIC:
+ locale = PerlEnv_getenv("LC_NUMERIC");
+ break;
+# endif
+# ifdef USE_LOCALE_MESSAGES
+ case LC_MESSAGES:
+ locale = PerlEnv_getenv("LC_MESSAGES");
+ break;
+# endif
+ default:
+ /* This is a category, like PAPER_SIZE that we don't
+ * know about; and so can't provide a wrapper. */
+ break;
+ }
+ if (! locale) {
+ locale = PerlEnv_getenv("LANG");
+ if (! locale) {
+ locale = "";
+ }
+ }
+# ifdef LC_ALL
+ }
+# endif
+ }
+
+ result = setlocale(category, locale);
+
+ if (! override_LC_ALL) {
+ return result;
+ }
+
+ /* Here the input locale was LC_ALL, and we have set it to what is in the
+ * LANG variable or the system default if there is no LANG. But these have
+ * lower priority than the other LC_foo variables, so override it for each
+ * one that is set. (If they are set to "", it means to use the same thing
+ * we just set LC_ALL to, so can skip) */
+# ifdef USE_LOCALE_TIME
+ result = PerlEnv_getenv("LC_TIME");
+ if (result && strNE(result, "")) {
+ setlocale(LC_TIME, result);
+ }
+# endif
+# ifdef USE_LOCALE_CTYPE
+ result = PerlEnv_getenv("LC_CTYPE");
+ if (result && strNE(result, "")) {
+ setlocale(LC_CTYPE, result);
+ }
+# endif
+# ifdef USE_LOCALE_COLLATE
+ result = PerlEnv_getenv("LC_COLLATE");
+ if (result && strNE(result, "")) {
+ setlocale(LC_COLLATE, result);
+ }
+# endif
+# ifdef USE_LOCALE_MONETARY
+ result = PerlEnv_getenv("LC_MONETARY");
+ if (result && strNE(result, "")) {
+ setlocale(LC_MONETARY, result);
+ }
+# endif
+# ifdef USE_LOCALE_NUMERIC
+ result = PerlEnv_getenv("LC_NUMERIC");
+ if (result && strNE(result, "")) {
+ setlocale(LC_NUMERIC, result);
+ }
+# endif
+# ifdef USE_LOCALE_MESSAGES
+ result = PerlEnv_getenv("LC_MESSAGES");
+ if (result && strNE(result, "")) {
+ setlocale(LC_MESSAGES, result);
+ }
+# endif
+
+ return setlocale(LC_ALL, NULL);
+
+}
+
+#endif
+
+