Like we have helper function __mingw_filename_cp() for determing code page
used by CRT library for filenames, add a new helper function named
__mingw_isleadbyte_cp() to check if particular character in supplied code
page is leading or not.

Use WinAPI function IsDBCSLeadByteEx() for its implementation. When the
IsDBCSLeadByteEx() function is not available then provide emulation code
taken from mingw-w64-libraries/winstorecompat/src/IsDBCSLeadByteEx.c.

API of the __mingw_isleadbyte_cp() function is similar to CRT function
_isleadbyte_l(), first argment is character and second argument is code page.
---
 mingw-w64-crt/Makefile.am                  |  1 +
 mingw-w64-crt/misc/__mingw_isleadbyte_cp.c | 36 ++++++++++++++++++++++
 mingw-w64-headers/crt/locale.h             |  3 ++
 3 files changed, 40 insertions(+)
 create mode 100644 mingw-w64-crt/misc/__mingw_isleadbyte_cp.c

diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index ff032f953493..1364472c2ab1 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -1257,6 +1257,7 @@ src_libmingwex=\
   misc/wmemset.c         misc/mingw-access.c \
   misc/ftw32.c           misc/ftw32i64.c            misc/ftw64.c            
misc/ftw64i32.c \
   misc/__mingw_filename_cp.c \
+  misc/__mingw_isleadbyte_cp.c \
   \
   ssp/chk_fail.c         ssp/gets_chk.c             ssp/memcpy_chk.c        
ssp/memmove_chk.c \
   ssp/mempcpy_chk.c \
diff --git a/mingw-w64-crt/misc/__mingw_isleadbyte_cp.c 
b/mingw-w64-crt/misc/__mingw_isleadbyte_cp.c
new file mode 100644
index 000000000000..54e645a646e4
--- /dev/null
+++ b/mingw-w64-crt/misc/__mingw_isleadbyte_cp.c
@@ -0,0 +1,36 @@
+/**
+ * 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.
+ */
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <locale.h>
+
+static BOOL WINAPI fallback_IsDBCSLeadByteEx(UINT cp, BYTE c)
+{
+  int i;
+  CPINFO cp_info;
+  if (GetCPInfo(cp, &cp_info) && cp_info.MaxCharSize > 1) {
+    for (i = 0; i < MAX_LEADBYTES && cp_info.LeadByte[i]; i += 2) {
+      if (c >= cp_info.LeadByte[i] && c <= cp_info.LeadByte[i+1])
+        return TRUE;
+    }
+  }
+  return FALSE;
+}
+_Static_assert(__builtin_types_compatible_p(typeof(fallback_IsDBCSLeadByteEx), 
typeof(IsDBCSLeadByteEx)), "Functions fallback_IsDBCSLeadByteEx() and 
IsDBCSLeadByteEx() are compatible");
+
+int __cdecl __mingw_isleadbyte_cp(int c, unsigned int cp)
+{
+  static __typeof(IsDBCSLeadByteEx) *call_IsDBCSLeadByteEx = NULL;
+  if (!call_IsDBCSLeadByteEx) {
+    HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
+    __typeof(IsDBCSLeadByteEx) *kernel32_IsDBCSLeadByteEx = kernel32 ? 
(__typeof(IsDBCSLeadByteEx)*)GetProcAddress(kernel32, "IsDBCSLeadByteEx") : 
NULL;
+    (void)InterlockedExchangePointer((PVOID*)&call_IsDBCSLeadByteEx, 
kernel32_IsDBCSLeadByteEx ?: fallback_IsDBCSLeadByteEx);
+  }
+  return call_IsDBCSLeadByteEx(cp, c);
+}
diff --git a/mingw-w64-headers/crt/locale.h b/mingw-w64-headers/crt/locale.h
index 1ec5a70edd7e..6a7807d4edd3 100644
--- a/mingw-w64-headers/crt/locale.h
+++ b/mingw-w64-headers/crt/locale.h
@@ -101,6 +101,9 @@ extern "C" {
   /* Get the code page that the CRT currently uses for filenames. */
   unsigned int __cdecl __mingw_filename_cp(void);
 
+  /* Variant of _isleadbyte_l() function which takes codepage (instead of 
locale_t). */
+  int __cdecl __mingw_isleadbyte_cp(int c, unsigned int cp);
+
 #ifndef _WLOCALE_DEFINED
 #define _WLOCALE_DEFINED
   _CRTIMP wchar_t *__cdecl _wsetlocale(int _Category,const wchar_t *_Locale);
-- 
2.20.1



_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to