diff options
Diffstat (limited to 'src/locale')
| -rw-r--r-- | src/locale/bind_textdomain_codeset.c | 6 | ||||
| -rw-r--r-- | src/locale/codepages.h | 11 | ||||
| -rw-r--r-- | src/locale/dcngettext.c | 3 | ||||
| -rw-r--r-- | src/locale/duplocale.c | 5 | ||||
| -rw-r--r-- | src/locale/gb18030utf.h | 206 | ||||
| -rw-r--r-- | src/locale/iconv.c | 50 | ||||
| -rw-r--r-- | src/locale/strtod_l.c | 22 |
7 files changed, 289 insertions, 14 deletions
diff --git a/src/locale/bind_textdomain_codeset.c b/src/locale/bind_textdomain_codeset.c index 5ebfd5e8..240e83ed 100644 --- a/src/locale/bind_textdomain_codeset.c +++ b/src/locale/bind_textdomain_codeset.c @@ -5,7 +5,9 @@ char *bind_textdomain_codeset(const char *domainname, const char *codeset) { - if (codeset && strcasecmp(codeset, "UTF-8")) + if (codeset && strcasecmp(codeset, "UTF-8")) { errno = EINVAL; - return NULL; + return 0; + } + return "UTF-8"; } diff --git a/src/locale/codepages.h b/src/locale/codepages.h index 4e236ef3..a254f0f5 100644 --- a/src/locale/codepages.h +++ b/src/locale/codepages.h @@ -286,6 +286,17 @@ "\323\174\103\215\64\365\124\123\213\77\336\150\263\115\66\375\164\363\12\55" "\255\304\42\261\57\266\234\162\17\56\260\240\162\113\56\263\310\62\66\50" +"cp858\0" +"\0\40" +"\307\360\223\216\70\344\200\123\316\71\352\254\203\316\73\356\260\103\114\61" +"\311\230\143\14\75\366\310\263\117\76\377\130\303\15\76\243\140\163\15\135" +"\341\264\63\217\76\361\104\243\212\56\277\270\302\112\57\274\204\262\312\56" +"\140\207\55\66\315\72\7\43\14\60\251\104\375\163\321\113\213\122\212\315" +"\67\363\274\163\316\63\367\74\316\60\110\13\175\65\325\116\373\254\65\51" +"\360\100\243\314\62\310\220\334\214\63\317\340\134\163\327\134\233\302\314\326" +"\323\174\103\215\64\365\124\123\213\77\336\150\263\115\66\375\164\363\12\55" +"\255\304\42\261\57\266\234\162\17\56\260\240\162\113\56\263\310\62\66\50" + "cp866\0" "\0\40" "\337\201\27\236\170\343\221\127\236\171\347\241\227\236\172" diff --git a/src/locale/dcngettext.c b/src/locale/dcngettext.c index d1e6c6d1..0b53286d 100644 --- a/src/locale/dcngettext.c +++ b/src/locale/dcngettext.c @@ -132,6 +132,9 @@ char *dcngettext(const char *domainname, const char *msgid1, const char *msgid2, struct binding *q; int old_errno = errno; + /* match gnu gettext behaviour */ + if (!msgid1) goto notrans; + if ((unsigned)category >= LC_ALL) goto notrans; if (!domainname) domainname = __gettextdomain(); diff --git a/src/locale/duplocale.c b/src/locale/duplocale.c index 030b64cb..5ce33ae6 100644 --- a/src/locale/duplocale.c +++ b/src/locale/duplocale.c @@ -3,6 +3,11 @@ #include "locale_impl.h" #include "libc.h" +#define malloc __libc_malloc +#define calloc undef +#define realloc undef +#define free undef + locale_t __duplocale(locale_t old) { locale_t new = malloc(sizeof *new); diff --git a/src/locale/gb18030utf.h b/src/locale/gb18030utf.h new file mode 100644 index 00000000..322a2440 --- /dev/null +++ b/src/locale/gb18030utf.h @@ -0,0 +1,206 @@ +{ 0x80, 36 }, +{ 0xa5, 2 }, +{ 0xa9, 7 }, +{ 0xb2, 5 }, +{ 0xb8, 31 }, +{ 0xd8, 8 }, +{ 0xe2, 6 }, +{ 0xeb, 1 }, +{ 0xee, 4 }, +{ 0xf4, 3 }, +{ 0xf8, 1 }, +{ 0xfb, 1 }, +{ 0xfd, 4 }, +{ 0x102, 17 }, +{ 0x114, 7 }, +{ 0x11c, 15 }, +{ 0x12c, 24 }, +{ 0x145, 3 }, +{ 0x149, 4 }, +{ 0x14e, 29 }, +{ 0x16c, 98 }, +{ 0x1cf, 1 }, +{ 0x1d1, 1 }, +{ 0x1d3, 1 }, +{ 0x1d5, 1 }, +{ 0x1d7, 1 }, +{ 0x1d9, 1 }, +{ 0x1db, 1 }, +{ 0x1dd, 28 }, +{ 0x1fa, 87 }, +{ 0x252, 15 }, +{ 0x262, 101 }, +{ 0x2c8, 1 }, +{ 0x2cc, 13 }, +{ 0x2da, 183 }, +{ 0x3a2, 1 }, +{ 0x3aa, 7 }, +{ 0x3c2, 1 }, +{ 0x3ca, 55 }, +{ 0x402, 14 }, +{ 0x450, 1 }, +{ 0x452, 7102 }, +{ 0x2011, 2 }, +{ 0x2017, 1 }, +{ 0x201a, 2 }, +{ 0x201e, 7 }, +{ 0x2027, 9 }, +{ 0x2031, 1 }, +{ 0x2034, 1 }, +{ 0x2036, 5 }, +{ 0x203c, 112 }, +{ 0x20ad, 86 }, +{ 0x2104, 1 }, +{ 0x2106, 3 }, +{ 0x210a, 12 }, +{ 0x2117, 10 }, +{ 0x2122, 62 }, +{ 0x216c, 4 }, +{ 0x217a, 22 }, +{ 0x2194, 2 }, +{ 0x219a, 110 }, +{ 0x2209, 6 }, +{ 0x2210, 1 }, +{ 0x2212, 3 }, +{ 0x2216, 4 }, +{ 0x221b, 2 }, +{ 0x2221, 2 }, +{ 0x2224, 1 }, +{ 0x2226, 1 }, +{ 0x222c, 2 }, +{ 0x222f, 5 }, +{ 0x2238, 5 }, +{ 0x223e, 10 }, +{ 0x2249, 3 }, +{ 0x224d, 5 }, +{ 0x2253, 13 }, +{ 0x2262, 2 }, +{ 0x2268, 6 }, +{ 0x2270, 37 }, +{ 0x2296, 3 }, +{ 0x229a, 11 }, +{ 0x22a6, 25 }, +{ 0x22c0, 82 }, +{ 0x2313, 333 }, +{ 0x246a, 10 }, +{ 0x249c, 100 }, +{ 0x254c, 4 }, +{ 0x2574, 13 }, +{ 0x2590, 3 }, +{ 0x2596, 10 }, +{ 0x25a2, 16 }, +{ 0x25b4, 8 }, +{ 0x25be, 8 }, +{ 0x25c8, 3 }, +{ 0x25cc, 2 }, +{ 0x25d0, 18 }, +{ 0x25e6, 31 }, +{ 0x2607, 2 }, +{ 0x260a, 54 }, +{ 0x2641, 1 }, +{ 0x2643, 2110 }, +{ 0x2e82, 2 }, +{ 0x2e85, 3 }, +{ 0x2e89, 2 }, +{ 0x2e8d, 10 }, +{ 0x2e98, 15 }, +{ 0x2ea8, 2 }, +{ 0x2eab, 3 }, +{ 0x2eaf, 4 }, +{ 0x2eb4, 2 }, +{ 0x2eb8, 3 }, +{ 0x2ebc, 14 }, +{ 0x2ecb, 293 }, +{ 0x2ffc, 4 }, +{ 0x3004, 1 }, +{ 0x3018, 5 }, +{ 0x301f, 2 }, +{ 0x302a, 20 }, +{ 0x303f, 2 }, +{ 0x3094, 7 }, +{ 0x309f, 2 }, +{ 0x30f7, 5 }, +{ 0x30ff, 6 }, +{ 0x312a, 246 }, +{ 0x322a, 7 }, +{ 0x3232, 113 }, +{ 0x32a4, 234 }, +{ 0x3390, 12 }, +{ 0x339f, 2 }, +{ 0x33a2, 34 }, +{ 0x33c5, 9 }, +{ 0x33cf, 2 }, +{ 0x33d3, 2 }, +{ 0x33d6, 113 }, +{ 0x3448, 43 }, +{ 0x3474, 298 }, +{ 0x359f, 111 }, +{ 0x360f, 11 }, +{ 0x361b, 765 }, +{ 0x3919, 85 }, +{ 0x396f, 96 }, +{ 0x39d1, 14 }, +{ 0x39e0, 147 }, +{ 0x3a74, 218 }, +{ 0x3b4f, 287 }, +{ 0x3c6f, 113 }, +{ 0x3ce1, 885 }, +{ 0x4057, 264 }, +{ 0x4160, 471 }, +{ 0x4338, 116 }, +{ 0x43ad, 4 }, +{ 0x43b2, 43 }, +{ 0x43de, 248 }, +{ 0x44d7, 373 }, +{ 0x464d, 20 }, +{ 0x4662, 193 }, +{ 0x4724, 5 }, +{ 0x472a, 82 }, +{ 0x477d, 16 }, +{ 0x478e, 441 }, +{ 0x4948, 50 }, +{ 0x497b, 2 }, +{ 0x497e, 4 }, +{ 0x4984, 1 }, +{ 0x4987, 20 }, +{ 0x499c, 3 }, +{ 0x49a0, 22 }, +{ 0x49b8, 703 }, +{ 0x4c78, 39 }, +{ 0x4ca4, 111 }, +{ 0x4d1a, 148 }, +{ 0x4daf, 81 }, +{ 0x9fa6, 14426 }, +{ 0xe76c, 1 }, +{ 0xe7c8, 1 }, +{ 0xe7e7, 13 }, +{ 0xe815, 1 }, +{ 0xe819, 5 }, +{ 0xe81f, 7 }, +{ 0xe827, 4 }, +{ 0xe82d, 4 }, +{ 0xe833, 8 }, +{ 0xe83c, 7 }, +{ 0xe844, 16 }, +{ 0xe856, 14 }, +{ 0xe865, 4295 }, +{ 0xf92d, 76 }, +{ 0xf97a, 27 }, +{ 0xf996, 81 }, +{ 0xf9e8, 9 }, +{ 0xf9f2, 26 }, +{ 0xfa10, 1 }, +{ 0xfa12, 1 }, +{ 0xfa15, 3 }, +{ 0xfa19, 6 }, +{ 0xfa22, 1 }, +{ 0xfa25, 2 }, +{ 0xfa2a, 1030 }, +{ 0xfe32, 1 }, +{ 0xfe45, 4 }, +{ 0xfe53, 1 }, +{ 0xfe58, 1 }, +{ 0xfe67, 1 }, +{ 0xfe6c, 149 }, +{ 0xff5f, 129 }, +{ 0xffe6, 26 }, diff --git a/src/locale/iconv.c b/src/locale/iconv.c index 3047c27b..4151411d 100644 --- a/src/locale/iconv.c +++ b/src/locale/iconv.c @@ -49,10 +49,10 @@ static const unsigned char charmaps[] = "ucs4\0utf32\0\0\313" "ucs2\0\0\314" "eucjp\0\0\320" -"shiftjis\0sjis\0\0\321" +"shiftjis\0sjis\0cp932\0\0\321" "iso2022jp\0\0\322" "gb18030\0\0\330" -"gbk\0\0\331" +"gbk\0cp936\0windows936\0\0\331" "gb2312\0\0\332" "big5\0bigfive\0cp950\0big5hkscs\0\0\340" "euckr\0ksc5601\0ksx1001\0cp949\0\0\350" @@ -74,6 +74,10 @@ static const unsigned short gb18030[126][190] = { #include "gb18030.h" }; +static const unsigned short gb18030utf[][2] = { +#include "gb18030utf.h" +}; + static const unsigned short big5[89][157] = { #include "big5.h" }; @@ -224,6 +228,8 @@ static unsigned uni_to_jis(unsigned c) } } +#define countof(a) (sizeof (a) / sizeof *(a)) + size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restrict out, size_t *restrict outb) { size_t x=0; @@ -339,7 +345,10 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri } else if (d-159 <= 252-159) { c++; d -= 159; + } else { + goto ilseq; } + if (c>=84) goto ilseq; c = jis0208[c][d]; if (!c) goto ilseq; break; @@ -403,6 +412,10 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri if (c < 128) break; if (c < 0xa1) goto ilseq; case GBK: + if (c == 128) { + c = 0x20ac; + break; + } case GB18030: if (c < 128) break; c -= 0x81; @@ -423,15 +436,24 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri d = *((unsigned char *)*in + 3); if (d-'0'>9) goto ilseq; c += d-'0'; - c += 128; - for (d=0; d<=c; ) { - k = 0; - for (int i=0; i<126; i++) - for (int j=0; j<190; j++) - if (gb18030[i][j]-d <= c-d) - k++; - d = c+1; - c += k; + /* Starting at 90 30 81 30 (189000), mapping is + * linear without gaps, to U+10000 and up. */ + if (c >= 189000) { + c -= 189000; + c += 0x10000; + if (c >= 0x110000) goto ilseq; + break; + } + /* Otherwise we must process an index into set + * of characters unmapped by 2-byte table. */ + for (int i=0; ; i++) { + if (i==countof(gb18030utf)) + goto ilseq; + if (c<gb18030utf[i][1]) { + c += gb18030utf[i][0]; + break; + } + c -= gb18030utf[i][1]; } break; } @@ -495,7 +517,7 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri if (c >= 93 || d >= 94) { c += (0xa1-0x81); d += 0xa1; - if (c >= 93 || c>=0xc6-0x81 && d>0x52) + if (c > 0xc6-0x81 || c==0xc6-0x81 && d>0x52) goto ilseq; if (d-'A'<26) d = d-'A'; else if (d-'a'<26) d = d-'a'+26; @@ -538,6 +560,10 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri if (*outb < k) goto toobig; memcpy(*out, tmp, k); } else k = wctomb_utf8(*out, c); + /* This failure condition should be unreachable, but + * is included to prevent decoder bugs from translating + * into advancement outside the output buffer range. */ + if (k>4) goto ilseq; *out += k; *outb -= k; break; diff --git a/src/locale/strtod_l.c b/src/locale/strtod_l.c new file mode 100644 index 00000000..574ba148 --- /dev/null +++ b/src/locale/strtod_l.c @@ -0,0 +1,22 @@ +#define _GNU_SOURCE +#include <stdlib.h> +#include <locale.h> + +float strtof_l(const char *restrict s, char **restrict p, locale_t l) +{ + return strtof(s, p); +} + +double strtod_l(const char *restrict s, char **restrict p, locale_t l) +{ + return strtod(s, p); +} + +long double strtold_l(const char *restrict s, char **restrict p, locale_t l) +{ + return strtold(s, p); +} + +weak_alias(strtof_l, __strtof_l); +weak_alias(strtod_l, __strtod_l); +weak_alias(strtold_l, __strtold_l); |
