crt: new implementation for btowc and wctob

Replacementes for C95 functions btowc and wctob now use mbrtowc
and wcrtomb respectively to perform conversion. This ensures that
their behavior is consistent with mbrtowc and wcrtomb functions.

Signed-off-by: Kirill Makurin <maiddaisuki@outlook.com>
diff --git a/mingw-w64-crt/misc/btowc.c b/mingw-w64-crt/misc/btowc.c
index c8fbd8e..caf2d95 100644
--- a/mingw-w64-crt/misc/btowc.c
+++ b/mingw-w64-crt/misc/btowc.c
@@ -7,6 +7,7 @@
 #define WIN32_LEAN_AND_MEAN
 #endif
 #include "mb_wc_common.h"
+#include <limits.h>
 #include <wchar.h>
 #include <stdio.h>
 #include <windows.h>
@@ -15,14 +16,16 @@
 {
   if (c == EOF)
     return (WEOF);
-  else
-    {
-      unsigned char ch = c;
-      wchar_t wc = WEOF;
-      if (!MultiByteToWideChar (___lc_codepage_func(), MB_ERR_INVALID_CHARS,
-                                (char*)&ch, 1, &wc, 1))
-        return WEOF;
 
-      return wc;
-    }
+  /* Use dummy string so that mbrtowc will never return (size_t)-2 */
+  char str[MB_LEN_MAX] = {(unsigned char) c, 0, 0, 0, 0};
+
+  wint_t    wc = WEOF;
+  mbstate_t state = {0};
+
+  if (mbrtowc (&wc, (char *) str, MB_CUR_MAX, &state) == (size_t) -1) {
+    return WEOF;
+  }
+
+  return wc;
 }
diff --git a/mingw-w64-crt/misc/wctob.c b/mingw-w64-crt/misc/wctob.c
index 995f6db..2fe6661 100644
--- a/mingw-w64-crt/misc/wctob.c
+++ b/mingw-w64-crt/misc/wctob.c
@@ -7,23 +7,28 @@
 #define WIN32_LEAN_AND_MEAN
 #endif
 #include "mb_wc_common.h"
+#include <limits.h>
 #include <wchar.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <windows.h>
 
-/* Return just the first byte after translating to multibyte.  */
-int wctob (wint_t wc )
+int wctob (wint_t wc)
 {
-    wchar_t w = wc;
-    char c;
-    int invalid_char = 0;
-    if (!WideCharToMultiByte (___lc_codepage_func(),
-			      0 /* Is this correct flag? */,
-			      &w, 1, &c, 1, NULL, &invalid_char)
-	 || invalid_char)
-      return EOF;
+  /* Return early */
+  if (IS_LOW_SURROGATE (wc) || IS_HIGH_SURROGATE (wc) || wc == WEOF) {
+    return EOF;
+  }
 
-    return (unsigned char) c;
+  mbstate_t state = {0};
+  /* Buffer large enough to hold any multibyte character */
+  char mbc[MB_LEN_MAX];
+
+  size_t length = wcrtomb (mbc, wc, &state);
+  if (length > 1) {
+    return EOF;
+  }
+
+  return (unsigned char) mbc[0];
 }