diff options
author | Bruce Mitchener <bruce.mitchener@gmail.com> | 2013-09-14 15:59:03 +0700 |
---|---|---|
committer | Bruce Mitchener <bruce.mitchener@gmail.com> | 2013-09-26 06:46:48 +0700 |
commit | 7d58080e9354e6e34cb70568ea20cfa410c17cae (patch) | |
tree | 318f5fc83b3477ca1114b1fb1ed7ad0a5036521e | |
parent | 690f8c8f80661b0c6f9e731a3ff9da31fecfa7fa (diff) |
Add a lot of locale code.
28 files changed, 375 insertions, 5 deletions
@@ -1282,6 +1282,10 @@ try: os.path.join('libc', 'gen', 'vwarnx.c'), os.path.join('libc', 'stdlib', 'strtod.c'), ] + musl_files = [ + ] + for directory, sources in musl_files: + libc_files += [os.path.join('libc', 'musl', 'src', directory, source) for source in sources] return build_libc('libc.bc', libc_files) def apply_libc(need): @@ -1319,6 +1323,32 @@ try: 'wctrans.c', 'wcwidth.c', ]], + ['locale', [ + 'iswalnum_l.c', + 'iswalpha_l.c', + 'iswblank_l.c', + 'iswcntrl_l.c', + 'iswctype_l.c', + 'iswdigit_l.c', + 'iswgraph_l.c', + 'iswlower_l.c', + 'iswprint_l.c', + 'iswpunct_l.c', + 'iswspace_l.c', + 'iswupper_l.c', + 'iswxdigit_l.c', + 'strfmon.c', + 'strxfrm.c', + 'towctrans_l.c', + 'towlower_l.c', + 'towupper_l.c', + 'wcscoll.c', + 'wcscoll_l.c', + 'wcsxfrm.c', + 'wcsxfrm_l.c', + 'wctrans_l.c', + 'wctype_l.c', + ]], ['multibyte', [ 'btowc.c', 'mblen.c', @@ -1345,7 +1375,7 @@ try: 'wcpcpy.c', 'wcpncpy.c', 'wcscasecmp.c', - # 'wcscasecmp_l.c', # XXX: alltypes.h issue + 'wcscasecmp_l.c', 'wcscat.c', 'wcschr.c', 'wcscmp.c', @@ -1354,7 +1384,7 @@ try: 'wcsdup.c', 'wcslen.c', 'wcsncasecmp.c', - # 'wcsncasecmp_l.c', # XXX: alltypes.h issue + 'wcsncasecmp_l.c', 'wcsncat.c', 'wcsncmp.c', 'wcsncpy.c', diff --git a/src/library.js b/src/library.js index 49f8e453..4bbff433 100644 --- a/src/library.js +++ b/src/library.js @@ -4084,6 +4084,7 @@ LibraryManager.library = { } }, _toupper: 'toupper', + toupper_l: 'toupper', tolower__asm: true, tolower__sig: 'ii', @@ -4094,54 +4095,65 @@ LibraryManager.library = { return (chr - {{{ charCode('A') }}} + {{{ charCode('a') }}})|0; }, _tolower: 'tolower', + tolower_l: 'tolower', // The following functions are defined as macros in glibc. islower: function(chr) { return chr >= {{{ charCode('a') }}} && chr <= {{{ charCode('z') }}}; }, + islower_l: 'islower', isupper: function(chr) { return chr >= {{{ charCode('A') }}} && chr <= {{{ charCode('Z') }}}; }, + isupper_l: 'isupper', isalpha: function(chr) { return (chr >= {{{ charCode('a') }}} && chr <= {{{ charCode('z') }}}) || (chr >= {{{ charCode('A') }}} && chr <= {{{ charCode('Z') }}}); }, + isalpha_l: 'isalpha', isdigit: function(chr) { return chr >= {{{ charCode('0') }}} && chr <= {{{ charCode('9') }}}; }, - isdigit_l: 'isdigit', // no locale support yet + isdigit_l: 'isdigit', isxdigit: function(chr) { return (chr >= {{{ charCode('0') }}} && chr <= {{{ charCode('9') }}}) || (chr >= {{{ charCode('a') }}} && chr <= {{{ charCode('f') }}}) || (chr >= {{{ charCode('A') }}} && chr <= {{{ charCode('F') }}}); }, - isxdigit_l: 'isxdigit', // no locale support yet + isxdigit_l: 'isxdigit', isalnum: function(chr) { return (chr >= {{{ charCode('0') }}} && chr <= {{{ charCode('9') }}}) || (chr >= {{{ charCode('a') }}} && chr <= {{{ charCode('z') }}}) || (chr >= {{{ charCode('A') }}} && chr <= {{{ charCode('Z') }}}); }, + isalnum_l: 'isalnum', ispunct: function(chr) { return (chr >= {{{ charCode('!') }}} && chr <= {{{ charCode('/') }}}) || (chr >= {{{ charCode(':') }}} && chr <= {{{ charCode('@') }}}) || (chr >= {{{ charCode('[') }}} && chr <= {{{ charCode('`') }}}) || (chr >= {{{ charCode('{') }}} && chr <= {{{ charCode('~') }}}); }, + ispunct_l: 'ispunct', isspace: function(chr) { return (chr == 32) || (chr >= 9 && chr <= 13); }, + isspace_l: 'isspace', isblank: function(chr) { return chr == {{{ charCode(' ') }}} || chr == {{{ charCode('\t') }}}; }, + isblank_l: 'isblank', iscntrl: function(chr) { return (0 <= chr && chr <= 0x1F) || chr === 0x7F; }, + iscntrl_l: 'iscntrl', isprint: function(chr) { return 0x1F < chr && chr < 0x7F; }, + isprint_l: 'isprint', isgraph: function(chr) { return 0x20 < chr && chr < 0x7F; }, + isgraph_l: 'isgraph', // Lookup tables for glibc ctype implementation. __ctype_b_loc: function() { // http://refspecs.freestandards.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/baselib---ctype-b-loc.html @@ -8884,7 +8896,7 @@ function autoAddDeps(object, name) { } // Add aborting stubs for various libc stuff needed by libc++ -['pthread_cond_signal', 'pthread_equal', 'wcstol', 'wcstoll', 'wcstoul', 'wcstoull', 'wcstof', 'wcstod', 'wcstold', 'swprintf', 'pthread_join', 'pthread_detach', 'strcoll_l', 'strxfrm_l', 'wcscoll_l', 'toupper_l', 'tolower_l', 'iswspace_l', 'iswprint_l', 'iswcntrl_l', 'iswupper_l', 'iswlower_l', 'iswalpha_l', 'iswdigit_l', 'iswpunct_l', 'iswxdigit_l', 'iswblank_l', 'wcsxfrm_l', 'towupper_l', 'towlower_l', 'catgets', 'catopen', 'catclose'].forEach(function(aborter) { +['pthread_cond_signal', 'pthread_equal', 'wcstol', 'wcstoll', 'wcstoul', 'wcstoull', 'wcstof', 'wcstod', 'wcstold', 'swprintf', 'pthread_join', 'pthread_detach', 'strcoll_l', 'catgets', 'catopen', 'catclose'].forEach(function(aborter) { LibraryManager.library[aborter] = function() { throw 'TODO: ' + aborter }; }); diff --git a/system/lib/libc/musl/src/internal/locale_impl.h b/system/lib/libc/musl/src/internal/locale_impl.h new file mode 100644 index 00000000..c268124f --- /dev/null +++ b/system/lib/libc/musl/src/internal/locale_impl.h @@ -0,0 +1,5 @@ +#include <locale.h> + +struct __locale { + int dummy; +}; diff --git a/system/lib/libc/musl/src/locale/iswalnum_l.c b/system/lib/libc/musl/src/locale/iswalnum_l.c new file mode 100644 index 00000000..c888060c --- /dev/null +++ b/system/lib/libc/musl/src/locale/iswalnum_l.c @@ -0,0 +1,6 @@ +#include <wctype.h> + +int iswalnum_l(wint_t c, locale_t l) +{ + return iswalnum(c); +} diff --git a/system/lib/libc/musl/src/locale/iswalpha_l.c b/system/lib/libc/musl/src/locale/iswalpha_l.c new file mode 100644 index 00000000..cd2be91e --- /dev/null +++ b/system/lib/libc/musl/src/locale/iswalpha_l.c @@ -0,0 +1,6 @@ +#include <wctype.h> + +int iswalpha_l(wint_t c, locale_t l) +{ + return iswalpha(c); +} diff --git a/system/lib/libc/musl/src/locale/iswblank_l.c b/system/lib/libc/musl/src/locale/iswblank_l.c new file mode 100644 index 00000000..f3a2691f --- /dev/null +++ b/system/lib/libc/musl/src/locale/iswblank_l.c @@ -0,0 +1,6 @@ +#include <wctype.h> + +int iswblank_l(wint_t c, locale_t l) +{ + return iswblank(c); +} diff --git a/system/lib/libc/musl/src/locale/iswcntrl_l.c b/system/lib/libc/musl/src/locale/iswcntrl_l.c new file mode 100644 index 00000000..7681fe09 --- /dev/null +++ b/system/lib/libc/musl/src/locale/iswcntrl_l.c @@ -0,0 +1,6 @@ +#include <wctype.h> + +int iswcntrl_l(wint_t c, locale_t l) +{ + return iswcntrl(c); +} diff --git a/system/lib/libc/musl/src/locale/iswctype_l.c b/system/lib/libc/musl/src/locale/iswctype_l.c new file mode 100644 index 00000000..13dfb1ed --- /dev/null +++ b/system/lib/libc/musl/src/locale/iswctype_l.c @@ -0,0 +1,9 @@ +#include <wctype.h> +#include "libc.h" + +int iswctype_l(wint_t c, wctype_t t, locale_t l) +{ + return iswctype(c, t); +} + +weak_alias(iswctype_l, __iswctype_l); diff --git a/system/lib/libc/musl/src/locale/iswdigit_l.c b/system/lib/libc/musl/src/locale/iswdigit_l.c new file mode 100644 index 00000000..3de678c2 --- /dev/null +++ b/system/lib/libc/musl/src/locale/iswdigit_l.c @@ -0,0 +1,6 @@ +#include <wctype.h> + +int iswdigit_l(wint_t c, locale_t l) +{ + return iswdigit(c); +} diff --git a/system/lib/libc/musl/src/locale/iswgraph_l.c b/system/lib/libc/musl/src/locale/iswgraph_l.c new file mode 100644 index 00000000..34df64fc --- /dev/null +++ b/system/lib/libc/musl/src/locale/iswgraph_l.c @@ -0,0 +1,6 @@ +#include <wctype.h> + +int iswgraph_l(wint_t c, locale_t l) +{ + return iswgraph(c); +} diff --git a/system/lib/libc/musl/src/locale/iswlower_l.c b/system/lib/libc/musl/src/locale/iswlower_l.c new file mode 100644 index 00000000..c52421a0 --- /dev/null +++ b/system/lib/libc/musl/src/locale/iswlower_l.c @@ -0,0 +1,6 @@ +#include <wctype.h> + +int iswlower_l(wint_t c, locale_t l) +{ + return iswlower(c); +} diff --git a/system/lib/libc/musl/src/locale/iswprint_l.c b/system/lib/libc/musl/src/locale/iswprint_l.c new file mode 100644 index 00000000..73d83ab3 --- /dev/null +++ b/system/lib/libc/musl/src/locale/iswprint_l.c @@ -0,0 +1,6 @@ +#include <wctype.h> + +int iswprint_l(wint_t c, locale_t l) +{ + return iswprint(c); +} diff --git a/system/lib/libc/musl/src/locale/iswpunct_l.c b/system/lib/libc/musl/src/locale/iswpunct_l.c new file mode 100644 index 00000000..831e0e54 --- /dev/null +++ b/system/lib/libc/musl/src/locale/iswpunct_l.c @@ -0,0 +1,6 @@ +#include <wctype.h> + +int iswpunct_l(wint_t c, locale_t l) +{ + return iswpunct(c); +} diff --git a/system/lib/libc/musl/src/locale/iswspace_l.c b/system/lib/libc/musl/src/locale/iswspace_l.c new file mode 100644 index 00000000..b507e9e3 --- /dev/null +++ b/system/lib/libc/musl/src/locale/iswspace_l.c @@ -0,0 +1,6 @@ +#include <wctype.h> + +int iswspace_l(wint_t c, locale_t l) +{ + return iswspace(c); +} diff --git a/system/lib/libc/musl/src/locale/iswupper_l.c b/system/lib/libc/musl/src/locale/iswupper_l.c new file mode 100644 index 00000000..fc988ef1 --- /dev/null +++ b/system/lib/libc/musl/src/locale/iswupper_l.c @@ -0,0 +1,6 @@ +#include <wctype.h> + +int iswupper_l(wint_t c, locale_t l) +{ + return iswupper(c); +} diff --git a/system/lib/libc/musl/src/locale/iswxdigit_l.c b/system/lib/libc/musl/src/locale/iswxdigit_l.c new file mode 100644 index 00000000..9527cf3e --- /dev/null +++ b/system/lib/libc/musl/src/locale/iswxdigit_l.c @@ -0,0 +1,6 @@ +#include <wctype.h> + +int iswxdigit_l(wint_t c, locale_t l) +{ + return iswxdigit(c); +} diff --git a/system/lib/libc/musl/src/locale/strfmon.c b/system/lib/libc/musl/src/locale/strfmon.c new file mode 100644 index 00000000..f510d9a4 --- /dev/null +++ b/system/lib/libc/musl/src/locale/strfmon.c @@ -0,0 +1,101 @@ +#include <stdio.h> +#include <ctype.h> +#include <stdarg.h> +#include <monetary.h> +#include <errno.h> +#include <stdarg.h> + +static ssize_t vstrfmon_l(char *s, size_t n, locale_t loc, const char *fmt, va_list ap) +{ + size_t l; + double x; + int fill, nogrp, negpar, nosym, left, intl; + int lp, rp, w, fw; + char *s0=s; + for (; n && *fmt; ) { + if (*fmt != '%') { + literal: + *s++ = *fmt++; + n--; + continue; + } + fmt++; + if (*fmt == '%') goto literal; + + fill = ' '; + nogrp = 0; + negpar = 0; + nosym = 0; + left = 0; + for (; ; fmt++) { + switch (*fmt) { + case '=': + fill = *++fmt; + continue; + case '^': + nogrp = 1; + continue; + case '(': + negpar = 1; + case '+': + continue; + case '!': + nosym = 1; + continue; + case '-': + left = 1; + continue; + } + break; + } + + for (fw=0; isdigit(*fmt); fmt++) + fw = 10*fw + (*fmt-'0'); + lp = 0; + rp = 2; + if (*fmt=='#') for (lp=0, fmt++; isdigit(*fmt); fmt++) + lp = 10*lp + (*fmt-'0'); + if (*fmt=='.') for (rp=0, fmt++; isdigit(*fmt); fmt++) + rp = 10*rp + (*fmt-'0'); + + intl = *fmt++ == 'i'; + + w = lp + 1 + rp; + if (!left && fw>w) w = fw; + + x = va_arg(ap, double); + l = snprintf(s, n, "%*.*f", w, rp, x); + if (l >= n) { + errno = E2BIG; + return -1; + } + s += l; + n -= l; + } + return s-s0; +} + +ssize_t strfmon_l(char *restrict s, size_t n, locale_t loc, const char *restrict fmt, ...) +{ + va_list ap; + ssize_t ret; + + va_start(ap, fmt); + ret = vstrfmon_l(s, n, loc, fmt, ap); + va_end(ap); + + return ret; +} + + +ssize_t strfmon(char *restrict s, size_t n, const char *restrict fmt, ...) +{ + va_list ap; + ssize_t ret; + + va_start(ap, fmt); + ret = vstrfmon_l(s, n, 0, fmt, ap); + va_end(ap); + + return ret; +} diff --git a/system/lib/libc/musl/src/locale/strxfrm.c b/system/lib/libc/musl/src/locale/strxfrm.c new file mode 100644 index 00000000..32c46193 --- /dev/null +++ b/system/lib/libc/musl/src/locale/strxfrm.c @@ -0,0 +1,18 @@ +#include <string.h> +#include <locale.h> +#include "libc.h" + +/* collate only by code points */ +size_t __strxfrm_l(char *restrict dest, const char *restrict src, size_t n, locale_t loc) +{ + size_t l = strlen(src); + if (n > l) strcpy(dest, src); + return l; +} + +size_t strxfrm(char *restrict dest, const char *restrict src, size_t n) +{ + return __strxfrm_l(dest, src, n, 0); +} + +weak_alias(__strxfrm_l, strxfrm_l); diff --git a/system/lib/libc/musl/src/locale/towctrans_l.c b/system/lib/libc/musl/src/locale/towctrans_l.c new file mode 100644 index 00000000..6222058c --- /dev/null +++ b/system/lib/libc/musl/src/locale/towctrans_l.c @@ -0,0 +1,6 @@ +#include <wctype.h> + +wint_t towctrans_l(wint_t c, wctrans_t t, locale_t l) +{ + return towctrans(c, t); +} diff --git a/system/lib/libc/musl/src/locale/towlower_l.c b/system/lib/libc/musl/src/locale/towlower_l.c new file mode 100644 index 00000000..aaaea370 --- /dev/null +++ b/system/lib/libc/musl/src/locale/towlower_l.c @@ -0,0 +1,9 @@ +#include <wctype.h> +#include "libc.h" + +wint_t towlower_l(wint_t c, locale_t l) +{ + return towlower(c); +} + +weak_alias(towlower_l, __towlower_l); diff --git a/system/lib/libc/musl/src/locale/towupper_l.c b/system/lib/libc/musl/src/locale/towupper_l.c new file mode 100644 index 00000000..ad02a4be --- /dev/null +++ b/system/lib/libc/musl/src/locale/towupper_l.c @@ -0,0 +1,9 @@ +#include <wctype.h> +#include "libc.h" + +wint_t towupper_l(wint_t c, locale_t l) +{ + return towupper(c); +} + +weak_alias(towupper_l, __towupper_l); diff --git a/system/lib/libc/musl/src/locale/wcscoll.c b/system/lib/libc/musl/src/locale/wcscoll.c new file mode 100644 index 00000000..20a60900 --- /dev/null +++ b/system/lib/libc/musl/src/locale/wcscoll.c @@ -0,0 +1,16 @@ +#include <wchar.h> +#include <locale.h> +#include "libc.h" + +/* FIXME: stub */ +int __wcscoll_l(const wchar_t *l, const wchar_t *r, locale_t locale) +{ + return wcscmp(l, r); +} + +int wcscoll(const wchar_t *l, const wchar_t *r) +{ + return __wcscoll_l(l, r, 0); +} + +weak_alias(__wcscoll_l, wcscoll_l); diff --git a/system/lib/libc/musl/src/locale/wcscoll_l.c b/system/lib/libc/musl/src/locale/wcscoll_l.c new file mode 100644 index 00000000..f257ec8d --- /dev/null +++ b/system/lib/libc/musl/src/locale/wcscoll_l.c @@ -0,0 +1,6 @@ +#include <wchar.h> + +int wcscoll_l(const wchar_t *l, const wchar_t *r, locale_t locale) +{ + return wcscoll(l, r); +} diff --git a/system/lib/libc/musl/src/locale/wcsxfrm.c b/system/lib/libc/musl/src/locale/wcsxfrm.c new file mode 100644 index 00000000..cb79c97e --- /dev/null +++ b/system/lib/libc/musl/src/locale/wcsxfrm.c @@ -0,0 +1,21 @@ +#include <wchar.h> +#include <locale.h> +#include "libc.h" + +/* collate only by code points */ +size_t __wcsxfrm_l(wchar_t *restrict dest, const wchar_t *restrict src, size_t n, locale_t loc) +{ + size_t l = wcslen(src); + if (l >= n) { + wmemcpy(dest, src, n-1); + dest[n-1] = 0; + } else wcscpy(dest, src); + return l; +} + +size_t wcsxfrm(wchar_t *restrict dest, const wchar_t *restrict src, size_t n) +{ + return __wcsxfrm_l(dest, src, n, 0); +} + +weak_alias(__wcsxfrm_l, wcsxfrm_l); diff --git a/system/lib/libc/musl/src/locale/wcsxfrm_l.c b/system/lib/libc/musl/src/locale/wcsxfrm_l.c new file mode 100644 index 00000000..66a00193 --- /dev/null +++ b/system/lib/libc/musl/src/locale/wcsxfrm_l.c @@ -0,0 +1,6 @@ +#include <wchar.h> + +size_t wcsxfrm_l(wchar_t *restrict dest, const wchar_t *restrict src, size_t n, locale_t locale) +{ + return wcsxfrm(dest, src, n); +} diff --git a/system/lib/libc/musl/src/locale/wctrans_l.c b/system/lib/libc/musl/src/locale/wctrans_l.c new file mode 100644 index 00000000..dae3381e --- /dev/null +++ b/system/lib/libc/musl/src/locale/wctrans_l.c @@ -0,0 +1,6 @@ +#include <wctype.h> + +wctrans_t wctrans_l(const char *s, locale_t l) +{ + return wctrans(s); +} diff --git a/system/lib/libc/musl/src/locale/wctype_l.c b/system/lib/libc/musl/src/locale/wctype_l.c new file mode 100644 index 00000000..601bab37 --- /dev/null +++ b/system/lib/libc/musl/src/locale/wctype_l.c @@ -0,0 +1,9 @@ +#include <wctype.h> +#include "libc.h" + +wctype_t wctype_l(const char *s, locale_t l) +{ + return wctype(s); +} + +weak_alias(wctype_l, __wctype_l); diff --git a/system/lib/libcextra.symbols b/system/lib/libcextra.symbols index a365271d..ba9f491e 100644 --- a/system/lib/libcextra.symbols +++ b/system/lib/libcextra.symbols @@ -1,20 +1,40 @@ + W __iswctype_l + T __strxfrm_l + W __towlower_l + W __towupper_l + T __wcscoll_l + T __wcsxfrm_l + W __wctype_l T btowc T ecvt T fcvt T gcvt T iswalnum + T iswalnum_l T iswalpha + T iswalpha_l T iswblank + T iswblank_l T iswcntrl + T iswcntrl_l T iswctype + T iswctype_l T iswdigit + T iswdigit_l T iswgraph + T iswgraph_l T iswlower + T iswlower_l T iswprint + T iswprint_l T iswpunct + T iswpunct_l T iswspace + T iswspace_l T iswupper + T iswupper_l T iswxdigit + T iswxdigit_l T mblen T mbrlen T mbrtowc @@ -23,21 +43,32 @@ T mbsrtowcs T mbstowcs T mbtowc + T strfmon + T strfmon_l + T strxfrm + W strxfrm_l T towctrans + T towctrans_l T towlower + T towlower_l T towupper + T towupper_l T wcpcpy T wcpncpy T wcrtomb T wcscasecmp + T wcscasecmp_l T wcscat T wcschr T wcscmp + T wcscoll + T wcscoll_l T wcscpy T wcscspn T wcsdup T wcslen T wcsncasecmp + T wcsncasecmp_l T wcsncat T wcsncmp T wcsncpy @@ -52,10 +83,14 @@ T wcstombs T wcswcs T wcswidth + T wcsxfrm + T wcsxfrm_l T wctob T wctomb T wctrans + T wctrans_l T wctype + T wctype_l T wcwidth T wmemchr T wmemcmp |