#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
#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
#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
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
#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
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
#define __PDCLIB_LOCALE_H __PDCLIB_LOCALE_H
#include <_PDCLIB_int.h>
#include <locale.h>
+#include <wctype.h>
#include <threads.h>
#include <stdlib.h>
_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;
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;
}
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
--- /dev/null
+Basic C Locale Support\r
+ - i.e. support for the basic (PDCLib-packaged) C locale only
\ No newline at end of file
--- /dev/null
+/* "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
--- /dev/null
+/* _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
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
#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
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;
},
};
+/* 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
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
#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
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