]> pd.if.org Git - pdclib/commitdiff
PDCLIB-1 (PDCLIB-3) Make wide character classification/collation information locale...
authorOwen Shepherd <owen.shepherd@e43.eu>
Thu, 21 Mar 2013 00:06:53 +0000 (00:06 +0000)
committerOwen Shepherd <owen.shepherd@e43.eu>
Thu, 21 Mar 2013 00:06:53 +0000 (00:06 +0000)
* locale_t has had _WCType + _WCTypeSize fields added to it
* iswctype, towctrans, towlower, towupper -> add _PDCLIB_*_l internal variations
* Added module "c_locale" which will provide default C locale implementation. So far just registers Unicode tables with provided locale
* win32 -> use new "c_locale" module. crt0 modifications.
* posix -> use new "c_locale" module. stdinit modifications

12 files changed:
functions/wctype/iswctype.c
functions/wctype/towctrans.c
functions/wctype/towlower.c
functions/wctype/towupper.c
internals/_PDCLIB_locale.h
opt/c_locale/README.txt [new file with mode: 0644]
opt/c_locale/_PDCLIB_clocale.h [new file with mode: 0644]
opt/c_locale/_PDCLIB_initclocale.c [new file with mode: 0644]
platform/posix/Config.jam
platform/posix/functions/_PDCLIB/_PDCLIB_stdinit.c
platform/win32/Config.jam
platform/win32/crt0.c

index 5c5f7ed1795efcf92624a3d19e7cedafb534b06e..d3de118ab82fa90441e5cec06991ac1d62d3f1a4 100644 (file)
@@ -8,17 +8,22 @@
 #ifndef REGTEST\r
 #include <_PDCLIB_locale.h>\r
 \r
-int iswctype( wint_t wc, wctype_t desc )\r
+int _PDCLIB_iswctype_l( wint_t wc, wctype_t desc, locale_t l )\r
 {\r
     wc = _PDCLIB_unpackwint( wc );\r
 \r
-    _PDCLIB_wcinfo_t *info = _PDCLIB_wcgetinfo( wc );\r
+    _PDCLIB_wcinfo_t *info = _PDCLIB_wcgetinfo( l, wc );\r
 \r
     if(!info) return 0;\r
 \r
     return info->flags & desc;\r
 }\r
 \r
+int iswctype( wint_t wc, wctype_t desc )\r
+{\r
+    return _PDCLIB_iswctype_l( wc, desc, _PDCLIB_threadlocale() );\r
+}\r
+\r
 #endif\r
 \r
 #ifdef TEST\r
index aea9b1a303ae28474e1d58435cdb917e7be91b91..f5f4a1dd38d2e3c49c1e8e91ee393695b648d116 100644 (file)
@@ -9,16 +9,21 @@
 #include <string.h>\r
 #include <_PDCLIB_locale.h>\r
 \r
-wint_t towctrans( wint_t wc, wctrans_t trans )\r
+wint_t _PDCLIB_towctrans_l( wint_t wc, wctrans_t trans, locale_t l )\r
 {\r
     switch( trans ) {\r
         case 0:                         return wc;\r
-        case _PDCLIB_WCTRANS_TOLOWER:   return towlower( wc );\r
-        case _PDCLIB_WCTRANS_TOUPPER:   return towupper( wc );\r
+        case _PDCLIB_WCTRANS_TOLOWER:   return _PDCLIB_towlower_l( wc, l );\r
+        case _PDCLIB_WCTRANS_TOUPPER:   return _PDCLIB_towupper_l( wc, l );\r
         default: abort();\r
     }\r
 }\r
 \r
+wint_t towctrans( wint_t wc, wctrans_t trans )\r
+{\r
+    return _PDCLIB_towctrans_l( wc, trans, _PDCLIB_threadlocale() );\r
+}\r
+\r
 #endif\r
 \r
 #ifdef TEST\r
index 7f9809c32af356208ffe5743960a4e448c6f5cbb..d8d56ece19bfde330b58140de489402a4cdaef3a 100644 (file)
@@ -8,10 +8,10 @@
 #ifndef REGTEST\r
 #include <_PDCLIB_locale.h>\r
 \r
-wint_t towlower( wint_t wc )\r
+wint_t _PDCLIB_towlower_l( wint_t wc, locale_t l )\r
 {\r
     wint_t uwc = _PDCLIB_unpackwint( wc );\r
-    _PDCLIB_wcinfo_t *info = _PDCLIB_wcgetinfo( uwc );\r
+    _PDCLIB_wcinfo_t *info = _PDCLIB_wcgetinfo( l, uwc );\r
     if( info && info->lower != uwc ) \r
     {\r
         wc = info->lower;\r
@@ -19,6 +19,11 @@ wint_t towlower( wint_t wc )
     return wc;\r
 }\r
 \r
+wint_t towlower( wint_t wc )\r
+{\r
+    return _PDCLIB_towlower_l( wc, _PDCLIB_threadlocale() );\r
+}\r
+\r
 #endif\r
 \r
 #ifdef TEST\r
index faac657501cac24ec24b262673befcdb97f5713f..7b96a6100b964b322105e0617f634ee7664d5bc6 100644 (file)
@@ -8,10 +8,10 @@
 #ifndef REGTEST\r
 #include <_PDCLIB_locale.h>\r
 \r
-wint_t towupper( wint_t wc )\r
+wint_t _PDCLIB_towupper_l( wint_t wc, locale_t l )\r
 {\r
     wint_t uwc = _PDCLIB_unpackwint( wc );\r
-    _PDCLIB_wcinfo_t *info = _PDCLIB_wcgetinfo( uwc );\r
+    _PDCLIB_wcinfo_t *info = _PDCLIB_wcgetinfo( l, uwc );\r
     if( info && info->upper != uwc ) \r
     {\r
         wc = info->upper;\r
@@ -19,6 +19,11 @@ wint_t towupper( wint_t wc )
     return wc;\r
 }\r
 \r
+wint_t towupper( wint_t wc )\r
+{\r
+    return _PDCLIB_towupper_l( wc, _PDCLIB_threadlocale() );\r
+}\r
+\r
 #endif\r
 \r
 #ifdef TEST\r
index 3b2deced51b3f519eb01ed49f1a325da69183955..fd47c9ab0c4b537835d374536d20d15e9b0a70e1 100644 (file)
@@ -2,6 +2,7 @@
 #define __PDCLIB_LOCALE_H __PDCLIB_LOCALE_H
 #include <_PDCLIB_int.h>
 #include <locale.h>
+#include <wctype.h>
 #include <threads.h>
 #include <stdlib.h>
 
@@ -78,6 +79,19 @@ typedef struct _PDCLIB_wcinfo
     _PDCLIB_wint_t   upper;
 } _PDCLIB_wcinfo_t;
 
+struct _PDCLIB_locale {
+    _PDCLIB_charcodec_t          _Codec;
+    struct lconv                 _Conv;
+
+    /* ctype / wctype */
+    _PDCLIB_wcinfo_t            *_WCType;
+    _PDCLIB_size_t               _WCTypeSize;
+    _PDCLIB_ctype_t             *_CType; 
+
+    /* perror/strerror */
+    char                        *_ErrnoStr[_PDCLIB_ERRNO_MAX];
+};
+
 extern _PDCLIB_wcinfo_t _PDCLIB_wcinfo[];
 extern size_t           _PDCLIB_wcinfo_size;
 
@@ -88,32 +102,32 @@ static inline int _PDCLIB_wcinfo_cmp( const void * _key, const void * _obj )
     return *key - obj->num;
 }
 
-static inline _PDCLIB_wcinfo_t * _PDCLIB_wcgetinfo( _PDCLIB_uint32_t num )
+static inline _PDCLIB_wcinfo_t * _PDCLIB_wcgetinfo( locale_t l, _PDCLIB_uint32_t num )
 {
     _PDCLIB_wcinfo_t *info = (_PDCLIB_wcinfo_t*) 
-        bsearch( &num, _PDCLIB_wcinfo, _PDCLIB_wcinfo_size, 
-                 sizeof( _PDCLIB_wcinfo[0] ), _PDCLIB_wcinfo_cmp );
+        bsearch( &num, l->_WCType, l->_WCTypeSize, 
+                 sizeof( l->_WCType[0] ), _PDCLIB_wcinfo_cmp );
 
     return info;
 }
 
-static inline _PDCLIB_wint_t _PDCLIB_unpackwint( _PDCLIB_wint_t wc )
+static inline wint_t _PDCLIB_unpackwint( wint_t wc )
 {
     if( sizeof(_PDCLIB_wchar_t) == 2 && sizeof(_PDCLIB_wint_t) == 4 ) {
         /* On UTF-16 platforms, as an extension accept a "packed surrogate"
          * encoding. We accept the surrogate pairs either way
          */
 
-        _PDCLIB_wint_t c = (wc & 0xF800F800);
+        wint_t c = (wc & 0xF800F800);
         if(c == (_PDCLIB_wint_t) 0xD800DC00) {
             // MSW: Lead, LSW: Trail
-            _PDCLIB_wint_t lead  = wc >> 16 & 0x3FF;
-            _PDCLIB_wint_t trail = wc       & 0x3FF;
+            wint_t lead  = wc >> 16 & 0x3FF;
+            wint_t trail = wc       & 0x3FF;
             wc = lead << 10 | trail;
         } else if(c == (_PDCLIB_wint_t) 0xDC00D800) {
             // MSW: Trail, LSW: Lead
-            _PDCLIB_wint_t trail = wc >> 16 & 0x3FF;
-            _PDCLIB_wint_t lead  = wc       & 0x3FF;
+            wint_t trail = wc >> 16 & 0x3FF;
+            wint_t lead  = wc       & 0x3FF;
             wc = lead << 10 | trail;
         }
 
@@ -121,15 +135,22 @@ static inline _PDCLIB_wint_t _PDCLIB_unpackwint( _PDCLIB_wint_t wc )
     return wc;
 }
 
-struct _PDCLIB_locale {
-    _PDCLIB_charcodec_t          _Codec;
-    struct lconv                 _Conv;
-
-    /* ctype */
-    _PDCLIB_ctype_t             *_CType; 
-
-    /* perror/strerror */
-    char                        *_ErrnoStr[_PDCLIB_ERRNO_MAX];
-};
+/* Internal xlocale-style WCType API */
+int _PDCLIB_iswalnum_l( wint_t _Wc, locale_t l );
+int _PDCLIB_iswalpha_l( wint_t _Wc, locale_t l );
+int _PDCLIB_iswblank_l( wint_t _Wc, locale_t l );
+int _PDCLIB_iswcntrl_l( wint_t _Wc, locale_t l );
+int _PDCLIB_iswdigit_l( wint_t _Wc, locale_t l );
+int _PDCLIB_iswgraph_l( wint_t _Wc, locale_t l );
+int _PDCLIB_iswlower_l( wint_t _Wc, locale_t l );
+int _PDCLIB_iswprint_l( wint_t _Wc, locale_t l );
+int _PDCLIB_iswpunct_l( wint_t _Wc, locale_t l );
+int _PDCLIB_iswspace_l( wint_t _Wc, locale_t l );
+int _PDCLIB_iswupper_l( wint_t _Wc, locale_t l );
+int _PDCLIB_iswxdigit_l( wint_t _Wc, locale_t l );
+int _PDCLIB_iswctype_l( wint_t _Wc, wctype_t _Desc, locale_t l );
+wint_t _PDCLIB_towlower_l( wint_t _Wc, locale_t l );
+wint_t _PDCLIB_towupper_l( wint_t _Wc, locale_t l );
+wint_t _PDCLIB_towctrans_l( wint_t _Wc, wctrans_t _Desc, locale_t l );
 
 #endif
diff --git a/opt/c_locale/README.txt b/opt/c_locale/README.txt
new file mode 100644 (file)
index 0000000..1fced17
--- /dev/null
@@ -0,0 +1,2 @@
+Basic C Locale Support\r
+    - i.e. support for the basic (PDCLib-packaged) C locale only
\ No newline at end of file
diff --git a/opt/c_locale/_PDCLIB_clocale.h b/opt/c_locale/_PDCLIB_clocale.h
new file mode 100644 (file)
index 0000000..ee51d28
--- /dev/null
@@ -0,0 +1,15 @@
+/* "C" Locale Support\r
+\r
+   This file is part of the Public Domain C Library (PDCLib).\r
+   Permission is granted to use, modify, and / or redistribute at will.\r
+*/\r
+\r
+#ifndef _PDCLIB_CLOCALE_H\r
+#define _PDCLIB_CLOCALE_H _PDCLIB_CLOCALE_H\r
+#include <locale.h>\r
+_PDCLIB_BEGIN_EXTERN_C\r
+\r
+void _PDCLIB_initclocale( locale_t l );\r
+\r
+_PDCLIB_END_EXTERN_C\r
+#endif // _PDCLIB_CLOCALE_H\r
diff --git a/opt/c_locale/_PDCLIB_initclocale.c b/opt/c_locale/_PDCLIB_initclocale.c
new file mode 100644 (file)
index 0000000..b1a0dbe
--- /dev/null
@@ -0,0 +1,29 @@
+/* _PDCLIB_initclocale( locale_t )\r
+\r
+   This file is part of the Public Domain C Library (PDCLib).\r
+   Permission is granted to use, modify, and / or redistribute at will.\r
+*/\r
+\r
+#ifndef REGTEST\r
+#include "_PDCLIB_clocale.h"\r
+#include "_PDCLIB_locale.h"\r
+\r
+void _PDCLIB_initclocale( locale_t l )\r
+{\r
+    // TODO: There will be more added here...\r
+\r
+    l->_WCType     = _PDCLIB_wcinfo;\r
+    l->_WCTypeSize = _PDCLIB_wcinfo_size;\r
+}\r
+\r
+#endif\r
+\r
+#ifdef TEST\r
+#include <_PDCLIB_test.h>\r
+\r
+int main()\r
+{\r
+    return TEST_RESULTS;\r
+}\r
+\r
+#endif
\ No newline at end of file
index 4fb8cf5a25da74e54175aae124b1a39486c8fea9..52d0e62e35826f17c6298f3f0d985e6ee4b409d0 100644 (file)
@@ -11,4 +11,4 @@ if $(OS) = "MACOSX" {
     PDCLIB_TEST_LINKLIBS += -lgcc ;\r
 }\r
 \r
-PDCLIB_OPTIONS = pthreads notime dlmalloc basecodecs ;
\ No newline at end of file
+PDCLIB_OPTIONS = pthreads notime dlmalloc basecodecs c_locale ;
\ No newline at end of file
index 7d246795343005361247e6805a584d28b4b1614b..0e562c6a6df8db48f1075fd749f0abf2f05b14ce 100644 (file)
@@ -18,6 +18,7 @@
 #ifndef REGTEST
 #include <_PDCLIB_io.h>
 #include <_PDCLIB_locale.h>
+#include <_PDCLIB_clocale.h>
 #include <threads.h>
 
 /* In a POSIX system, stdin / stdout / stderr are equivalent to the (int) file
@@ -79,14 +80,6 @@ FILE * stdout = &_PDCLIB_sout;
 FILE * stderr = &_PDCLIB_serr;
 
 tss_t _PDCLIB_locale_tss;
-/* Todo: Better solution than this! */
-__attribute__((constructor)) void init_stdio(void)
-{
-    tss_create(&_PDCLIB_locale_tss, (tss_dtor_t) freelocale);
-    mtx_init(&stdin->lock,  mtx_recursive);
-    mtx_init(&stdout->lock, mtx_recursive);
-    mtx_init(&stderr->lock, mtx_recursive);
-}
 
 /* FIXME: This approach is a possible attack vector. */
 FILE * _PDCLIB_filelist = &_PDCLIB_sin;
@@ -394,6 +387,16 @@ struct _PDCLIB_locale _PDCLIB_global_locale = {
     },
 };
 
+/* Todo: Better solution than this! */
+__attribute__((constructor)) void init_stdio(void)
+{
+    _PDCLIB_initclocale( &_PDCLIB_global_locale );
+    tss_create(&_PDCLIB_locale_tss, (tss_dtor_t) freelocale);
+    mtx_init(&stdin->lock,  mtx_recursive);
+    mtx_init(&stdout->lock, mtx_recursive);
+    mtx_init(&stderr->lock, mtx_recursive);
+}
+
 #endif
 
 #ifdef TEST
index 77be30586dae7f5403e9a9f3c05cf92f01e4fa00..baac82e745e4b281b53f4602d0144085e692bdd2 100644 (file)
@@ -23,6 +23,6 @@ if $(PDCLIB_TOOLCHAIN) = "gcc" {
     EXIT ;\r
 }\r
 \r
-PDCLIB_OPTIONS = notime dlmalloc mincoll tss_errno basecodecs ;\r
+PDCLIB_OPTIONS = notime dlmalloc mincoll tss_errno basecodecs c_locale ;\r
 \r
 CRT0 = [ FDirName platform win32 crt0$(SUFOBJ) ] ;
\ No newline at end of file
index bead33206c1541a8f782a52cca59abb2c6c68ce5..533ee98b862785cb6cabaee6be391629bf7bedd6 100644 (file)
@@ -7,6 +7,7 @@
 #include <windows.h>\r
 #include <_PDCLIB_io.h>\r
 #include <_PDCLIB_locale.h>\r
+#include <_PDCLIB_clocale.h>\r
 \r
 static char ** argvToAnsi( wchar_t ** wargv, int argc )\r
 {\r
@@ -116,6 +117,8 @@ void __cdecl mainCRTStartup( void )
     wargv = CommandLineToArgvW(cl, &argc);\r
     argv  = argvToAnsi(wargv, argc);\r
 \r
+    _PDCLIB_initclocale( &_PDCLIB_global_locale );\r
+\r
     if(tss_create(&_PDCLIB_locale_tss, (tss_dtor_t) freelocale) \r
             != thrd_success) {\r
         fputs( "Error during C runtime initialization: "\r