crt: Improve support for ___lc_codepage_func() function

CRT libraries msvcrt.dll and msvcrtd.dll since their first version from
Visual C++ 4.2 provide symbol for global variable __lc_codepage.

So do not use GetProcAddress() for __lc_codepage symbol and instead
directly reference it at compile time. It means that the setlocale() hack
is not needed to compile for msvcrt.dll and msvcrtd.dll builds at all.

Split the current lc_locale_func.c source file into two files:
___lc_codepage_func.c and ___lc_codepage_func_emul.c.

Source file ___lc_codepage_func.c will use either ___lc_codepage_func() via
GetProcAddress() for msvcrt.dll builds or fallback to __lc_codepage global
variable by direct reference.

Source file ___lc_codepage_func_emul.c will use emulation via the
setlocale() hack. This is needed only for msvcrt40.dll and older CRTs.

Signed-off-by: Martin Storsjö <martin@martin.st>
diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index 6cabe04..498b673 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -549,6 +549,7 @@
   misc/msvcrt__getmainargs.c \
   misc/msvcrt__wgetmainargs.c \
   math/i386__copysignf.c \
+  misc/___lc_codepage_func.c \
   misc/___lc_handle_func.c \
   misc/___mb_cur_max_func.c \
   misc/__p__osplatform.c \
@@ -569,7 +570,6 @@
   misc/_set_fmode.c \
   misc/_time64.c \
   misc/imaxabs.c \
-  misc/lc_locale_func.c \
   misc/output_format.c \
   misc/_get_errno.c \
   misc/_set_errno.c \
@@ -852,6 +852,7 @@
   stdio/fsetpos.c
 
 src_pre_msvcrt60=\
+  misc/___lc_codepage_func_emul.c \
   misc/__badioinfo.c \
   misc/__p__osplatform_emul.c \
   stdio/atoll.c \
@@ -867,7 +868,6 @@
   misc/_aligned_offset_realloc.c \
   misc/_aligned_realloc.c \
   misc/_time64.c \
-  misc/lc_locale_func.c \
   misc/strtoimax.c \
   misc/strtoumax.c \
   misc/wcstoimax.c \
@@ -1014,6 +1014,7 @@
   $(src_pre_msvcr100) \
   $(src_pre_msvcr110) \
   $(src_pre_msvcr120) \
+  misc/___lc_codepage_func.c \
   misc/___lc_handle_func.c \
   misc/msvcrt__getmainargs.c \
   misc/msvcrt__wgetmainargs.c
diff --git a/mingw-w64-crt/misc/___lc_codepage_func.c b/mingw-w64-crt/misc/___lc_codepage_func.c
new file mode 100644
index 0000000..91ef999
--- /dev/null
+++ b/mingw-w64-crt/misc/___lc_codepage_func.c
@@ -0,0 +1,20 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include <locale.h>
+
+extern unsigned int *__MINGW_IMP_SYMBOL(__lc_codepage);
+
+static unsigned int __cdecl emu____lc_codepage_func(void)
+{
+    return *__MINGW_IMP_SYMBOL(__lc_codepage);
+}
+
+#define RETT unsigned int
+#define FUNC ___lc_codepage_func
+#define ARGS void
+#define CALL
+#include "msvcrt_or_emu_glue.h"
diff --git a/mingw-w64-crt/misc/___lc_codepage_func_emul.c b/mingw-w64-crt/misc/___lc_codepage_func_emul.c
new file mode 100644
index 0000000..4df3dcb
--- /dev/null
+++ b/mingw-w64-crt/misc/___lc_codepage_func_emul.c
@@ -0,0 +1,17 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+
+unsigned int __cdecl ___lc_codepage_func(void)
+{
+    /* locale :: "lang[_country[.code_page]]" | ".code_page"  */
+    const char *cp_str = strchr(setlocale(LC_CTYPE, NULL), '.');
+    return cp_str ? atoi(cp_str + 1) : 0;
+}
+unsigned int (__cdecl *__MINGW_IMP_SYMBOL(___lc_codepage_func))(void) = ___lc_codepage_func;
diff --git a/mingw-w64-crt/misc/lc_locale_func.c b/mingw-w64-crt/misc/lc_locale_func.c
deleted file mode 100644
index 8f9ccd4..0000000
--- a/mingw-w64-crt/misc/lc_locale_func.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#define __lc_codepage __dummy_lc_codepage
-#define ___lc_codepage_func __dummy____lc_codepage_func
-#include <windows.h>
-#include <locale.h>
-
-#undef __lc_codepage
-#undef ___lc_codepage_func
-#include "mb_wc_common.h"
-
-static unsigned int __cdecl setlocale_codepage_hack(void)
-{
-    /* locale :: "lang[_country[.code_page]]" | ".code_page"  */
-    const char *cp_str = strchr (setlocale(LC_CTYPE, NULL), '.');
-    return cp_str ? atoi(cp_str + 1) : 0;
-}
-
-#ifndef __LIBMSVCRT_OS__
-
-unsigned int (__cdecl *__MINGW_IMP_SYMBOL(___lc_codepage_func))(void) = setlocale_codepage_hack;
-
-#else
-
-#include <msvcrt.h>
-
-static unsigned int *msvcrt__lc_codepage;
-static unsigned int __cdecl msvcrt___lc_codepage_func(void)
-{
-    return *msvcrt__lc_codepage;
-}
-
-static unsigned int __cdecl init_codepage_func(void);
-unsigned int (__cdecl *__MINGW_IMP_SYMBOL(___lc_codepage_func))(void) = init_codepage_func;
-
-static unsigned int __cdecl init_codepage_func(void)
-{
-    HMODULE msvcrt = __mingw_get_msvcrt_handle();
-    unsigned int (__cdecl *func)(void) = NULL;
-
-    if(msvcrt) {
-        func = (void*)GetProcAddress(msvcrt, "___lc_codepage_func");
-        if(!func) {
-            msvcrt__lc_codepage = (unsigned int*)GetProcAddress(msvcrt, "__lc_codepage");
-            if(msvcrt__lc_codepage)
-                func = msvcrt___lc_codepage_func;
-        }
-    }
-
-    if(!func)
-        func = setlocale_codepage_hack;
-
-    return (__MINGW_IMP_SYMBOL(___lc_codepage_func) = func)();
-}
-
-#endif
-
-unsigned int __cdecl ___lc_codepage_func(void)
-{
-    return __MINGW_IMP_SYMBOL(___lc_codepage_func)();
-}