Add localedef(1), a locale definition generator tool
[dragonfly.git] / usr.bin / localedef / wide.c
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11
12 /*
13  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
14  * Copyright 2012 Garrett D'Amore <garrett@damore.org>  All rights reserved.
15  * Copyright 2015 John Marino <draco@marino.st>
16  */
17
18 /*
19  * The functions in this file convert from the standard multibyte forms
20  * to the wide character forms used internally by libc.  Unfortunately,
21  * this approach means that we need a method for each and every encoding.
22  */
23
24 #include <stdlib.h>
25 #include <wchar.h>
26 #include <string.h>
27 #include <sys/types.h>
28 #include "localedef.h"
29
30 static int towide_none(wchar_t *, const char *, unsigned);
31 static int towide_utf8(wchar_t *, const char *, unsigned);
32 static int towide_big5(wchar_t *, const char *, unsigned);
33 static int towide_gbk(wchar_t *, const char *, unsigned);
34 static int towide_gb2312(wchar_t *, const char *, unsigned);
35 static int towide_gb18030(wchar_t *, const char *, unsigned);
36 static int towide_mskanji(wchar_t *, const char *, unsigned);
37 static int towide_euccn(wchar_t *, const char *, unsigned);
38 static int towide_eucjp(wchar_t *, const char *, unsigned);
39 static int towide_euckr(wchar_t *, const char *, unsigned);
40 static int towide_euctw(wchar_t *, const char *, unsigned);
41
42 static int tomb_none(char *, wchar_t);
43 static int tomb_utf8(char *, wchar_t);
44 static int tomb_mbs(char *, wchar_t);
45
46 static int (*_towide)(wchar_t *, const char *, unsigned) = towide_none;
47 static int (*_tomb)(char *, wchar_t) = tomb_none;
48 static const char *_encoding = "NONE";
49 static int _nbits = 7;
50
51 /*
52  * Table of supported encodings.  We only bother to list the multibyte
53  * encodings here, because single byte locales are handed by "NONE".
54  */
55 static struct {
56         const char *name;
57         /* the name that the underlying libc implemenation uses */
58         const char *cname;
59         /* the maximum number of bits required for priorities */
60         int nbits;
61         int (*towide)(wchar_t *, const char *, unsigned);
62         int (*tomb)(char *, wchar_t);
63 } mb_encodings[] = {
64         /*
65          * UTF8 values max out at 0x1fffff (although in theory there could
66          * be later extensions, but it won't happen.)  This means we only need
67          * 21 bits to be able to encode the entire range of priorities.
68          */
69         { "UTF-8",      "UTF-8",        21, towide_utf8, tomb_utf8 },
70         { "UTF8",       "UTF-8",        21, towide_utf8, tomb_utf8 },
71         { "utf8",       "UTF-8",        21, towide_utf8, tomb_utf8 },
72         { "utf-8",      "UTF-8",        21, towide_utf8, tomb_utf8 },
73
74         { "EUC-CN",     "EUC-CN",       16, towide_euccn, tomb_mbs },
75         { "eucCN",      "EUC-CN",       16, towide_euccn, tomb_mbs },
76         /*
77          * Becuase the 3-byte form of EUC-JP use the same leading byte,
78          * only 17 bits required to provide unique priorities.  (The low
79          * bit of that first byte is set.)  By setting this value low,
80          * we can get by with only 3 bytes in the strxfrm expansion.
81          */
82         { "EUC-JP",     "EUC-JP",       17, towide_eucjp, tomb_mbs },
83         { "eucJP",      "EUC-JP",       17, towide_eucjp, tomb_mbs },
84
85         { "EUC-KR",     "EUC-KR",       16, towide_euckr, tomb_mbs },
86         { "eucKR",      "EUC-KR",       16, towide_euckr, tomb_mbs },
87         /*
88          * EUC-TW uses 2 bytes most of the time, but 4 bytes if the
89          * high order byte is 0x8E.  However, with 4 byte encodings,
90          * the third byte will be A0-B0.  So we only need to consider
91          * the lower order 24 bits for collation.
92          */
93         { "EUC-TW",     "EUC-TW",       24, towide_euctw, tomb_mbs },
94         { "eucTW",      "EUC-TW",       24, towide_euctw, tomb_mbs },
95
96         { "MS_Kanji",   "MSKanji",      16, towide_mskanji, tomb_mbs },
97         { "MSKanji",    "MSKanji",      16, towide_mskanji, tomb_mbs },
98         { "PCK",        "MSKanji",      16, towide_mskanji, tomb_mbs },
99         { "SJIS",       "MSKanji",      16, towide_mskanji, tomb_mbs },
100         { "Shift_JIS",  "MSKanji",      16, towide_mskanji, tomb_mbs },
101
102         { "BIG5",       "BIG5",         16, towide_big5, tomb_mbs },
103         { "big5",       "BIG5",         16, towide_big5, tomb_mbs },
104         { "Big5",       "BIG5",         16, towide_big5, tomb_mbs },
105
106         { "GBK",        "GBK",          16, towide_gbk, tomb_mbs },
107
108         /*
109          * GB18030 can get away with just 31 bits.  This is because the
110          * high order bit is always set for 4 byte values, and the
111          * at least one of the other bits in that 4 byte value will
112          * be non-zero.
113          */
114         { "GB18030",    "GB18030",      31, towide_gb18030, tomb_mbs },
115
116         /*
117          * This should probably be an aliase for euc-cn, or vice versa.
118          */
119         { "GB2312",     "GB2312",       16, towide_gb2312, tomb_mbs },
120
121         { NULL, NULL, 0, 0, 0 },
122 };
123
124 static char *
125 show_mb(const char *mb)
126 {
127         static char buf[64];
128
129         /* ASCII stuff we just print */
130         if (isascii(*mb) && isgraph(*mb)) {
131                 buf[0] = *mb;
132                 buf[1] = 0;
133                 return (buf);
134         }
135         buf[0] = 0;
136         while (*mb != 0) {
137                 char scr[8];
138                 (void) snprintf(scr, sizeof (scr), "\\x%02x", *mb);
139                 (void) strlcat(buf, scr, sizeof (buf));
140                 mb++;
141         }
142         return (buf);
143 }
144
145 static char     *widemsg;
146
147 void
148 werr(const char *fmt, ...)
149 {
150         char    *msg;
151
152         va_list va;
153         va_start(va, fmt);
154         (void) vasprintf(&msg, fmt, va);
155         va_end(va);
156
157         free(widemsg);
158         widemsg = msg;
159 }
160
161 /*
162  * This is used for 8-bit encodings.
163  */
164 int
165 towide_none(wchar_t *c, const char *mb, unsigned n __unused)
166 {
167         if (mb_cur_max != 1) {
168                 werr("invalid or unsupported multibyte locale");
169                 return (-1);
170         }
171         *c = (uint8_t)*mb;
172         return (1);
173 }
174
175 int
176 tomb_none(char *mb, wchar_t wc)
177 {
178         if (mb_cur_max != 1) {
179                 werr("invalid or unsupported multibyte locale");
180                 return (-1);
181         }
182         *(uint8_t *)mb = (wc & 0xff);
183         mb[1] = 0;
184         return (1);
185 }
186
187 /*
188  * UTF-8 stores wide characters in UTF-32 form.
189  */
190 int
191 towide_utf8(wchar_t *wc, const char *mb, unsigned n)
192 {
193         wchar_t c;
194         int     nb;
195         int     lv;     /* lowest legal value */
196         int     i;
197         const uint8_t *s = (const uint8_t *)mb;
198
199         c = *s;
200
201         if ((c & 0x80) == 0) {
202                 /* 7-bit ASCII */
203                 *wc = c;
204                 return (1);
205         } else if ((c & 0xe0) == 0xc0) {
206                 /* u80-u7ff - two bytes encoded */
207                 nb = 2;
208                 lv = 0x80;
209                 c &= ~0xe0;
210         } else if ((c & 0xf0) == 0xe0) {
211                 /* u800-uffff - three bytes encoded */
212                 nb = 3;
213                 lv = 0x800;
214                 c &= ~0xf0;
215         } else if ((c & 0xf8) == 0xf0) {
216                 /* u1000-u1fffff - four bytes encoded */
217                 nb = 4;
218                 lv = 0x1000;
219                 c &= ~0xf8;
220         } else {
221                 /* 5 and 6 byte encodings are not legal unicode */
222                 werr("utf8 encoding too large (%s)", show_mb(mb));
223                 return (-1);
224         }
225         if (nb > (int)n) {
226                 werr("incomplete utf8 sequence (%s)", show_mb(mb));
227                 return (-1);
228         }
229
230         for (i = 1; i < nb; i++) {
231                 if (((s[i]) & 0xc0) != 0x80) {
232                         werr("illegal utf8 byte (%x)", s[i]);
233                         return (-1);
234                 }
235                 c <<= 6;
236                 c |= (s[i] & 0x3f);
237         }
238
239         if (c < lv) {
240                 werr("illegal redundant utf8 encoding (%s)", show_mb(mb));
241                 return (-1);
242         }
243         *wc = c;
244         return (nb);
245 }
246
247 int
248 tomb_utf8(char *mb, wchar_t wc)
249 {
250         uint8_t *s = (uint8_t *)mb;
251         uint8_t msk;
252         int cnt;
253         int i;
254
255         if (wc <= 0x7f) {
256                 s[0] = wc & 0x7f;
257                 s[1] = 0;
258                 return (1);
259         }
260         if (wc <= 0x7ff) {
261                 cnt = 2;
262                 msk = 0xc0;
263         } else if (wc <= 0xffff) {
264                 cnt = 3;
265                 msk = 0xe0;
266         } else if (wc <= 0x1fffff) {
267                 cnt = 4;
268                 msk = 0xf0;
269         } else {
270                 werr("illegal uf8 char (%x)", wc);
271                 return (-1);
272         }
273         for (i = cnt - 1; i; i--) {
274                 s[i] = (wc & 0x3f) | 0x80;
275                 wc >>= 6;
276         }
277         s[0] = (msk) | wc;
278         s[cnt] = 0;
279         return (cnt);
280 }
281
282 /*
283  * Several encodings share a simplistic dual byte encoding.  In these
284  * forms, they all indicate that a two byte sequence is to be used if
285  * the first byte has its high bit set.  They all store this simple
286  * encoding as a 16-bit value, although a great many of the possible
287  * code points are not used in most character sets.  This gives a possible
288  * set of just over 32,000 valid code points.
289  *
290  * 0x00 - 0x7f          - 1 byte encoding
291  * 0x80 - 0x7fff        - illegal
292  * 0x8000 - 0xffff      - 2 byte encoding
293  */
294
295 #pragma GCC diagnostic push
296 #pragma GCC diagnostic ignored "-Wcast-qual"
297
298 static int
299 towide_dbcs(wchar_t *wc, const char *mb, unsigned n)
300 {
301         wchar_t c;
302
303         c = *(uint8_t *)mb;
304
305         if ((c & 0x80) == 0) {
306                 /* 7-bit */
307                 *wc = c;
308                 return (1);
309         }
310         if (n < 2) {
311                 werr("incomplete character sequence (%s)", show_mb(mb));
312                 return (-1);
313         }
314
315         /* Store both bytes as a single 16-bit wide. */
316         c <<= 8;
317         c |= (uint8_t)(mb[1]);
318         *wc = c;
319         return (2);
320 }
321
322 /*
323  * Most multibyte locales just convert the wide character to the multibyte
324  * form by stripping leading null bytes, and writing the 32-bit quantity
325  * in big-endian order.
326  */
327 int
328 tomb_mbs(char *mb, wchar_t wc)
329 {
330         uint8_t *s = (uint8_t *)mb;
331         int     n = 0, c;
332
333         if ((wc & 0xff000000U) != 0) {
334                 n = 4;
335         } else if ((wc & 0x00ff0000U) != 0) {
336                 n = 3;
337         } else if ((wc & 0x0000ff00U) != 0) {
338                 n = 2;
339         } else {
340                 n = 1;
341         }
342         c = n;
343         while (n) {
344                 n--;
345                 s[n] = wc & 0xff;
346                 wc >>= 8;
347         }
348         /* ensure null termination */
349         s[c] = 0;
350         return (c);
351 }
352
353
354 /*
355  * big5 is a simple dual byte character set.
356  */
357 int
358 towide_big5(wchar_t *wc, const char *mb, unsigned n)
359 {
360         return (towide_dbcs(wc, mb, n));
361 }
362
363 /*
364  * GBK encodes wides in the same way that big5 does, the high order
365  * bit of the first byte indicates a double byte character.
366  */
367 int
368 towide_gbk(wchar_t *wc, const char *mb, unsigned n)
369 {
370         return (towide_dbcs(wc, mb, n));
371 }
372
373 /*
374  * GB2312 is another DBCS.  Its cleaner than others in that the second
375  * byte does not encode ASCII, but it supports characters.
376  */
377 int
378 towide_gb2312(wchar_t *wc, const char *mb, unsigned n)
379 {
380         return (towide_dbcs(wc, mb, n));
381 }
382
383 /*
384  * GB18030.  This encodes as 8, 16, or 32-bits.
385  * 7-bit values are in 1 byte,  4 byte sequences are used when
386  * the second byte encodes 0x30-39 and all other sequences are 2 bytes.
387  */
388 int
389 towide_gb18030(wchar_t *wc, const char *mb, unsigned n)
390 {
391         wchar_t c;
392
393         c = *(uint8_t *)mb;
394
395         if ((c & 0x80) == 0) {
396                 /* 7-bit */
397                 *wc = c;
398                 return (1);
399         }
400         if (n < 2) {
401                 werr("incomplete character sequence (%s)", show_mb(mb));
402                 return (-1);
403         }
404
405         /* pull in the second byte */
406         c <<= 8;
407         c |= (uint8_t)(mb[1]);
408
409         if (((c & 0xff) >= 0x30) && ((c & 0xff) <= 0x39)) {
410                 if (n < 4) {
411                         werr("incomplete 4-byte character sequence (%s)",
412                             show_mb(mb));
413                         return (-1);
414                 }
415                 c <<= 8;
416                 c |= (uint8_t)(mb[2]);
417                 c <<= 8;
418                 c |= (uint8_t)(mb[3]);
419                 *wc = c;
420                 return (4);
421         }
422
423         *wc = c;
424         return (2);
425 }
426
427 /*
428  * MS-Kanji (aka SJIS) is almost a clean DBCS like the others, but it
429  * also has a range of single byte characters above 0x80.  (0xa1-0xdf).
430  */
431 int
432 towide_mskanji(wchar_t *wc, const char *mb, unsigned n)
433 {
434         wchar_t c;
435
436         c = *(uint8_t *)mb;
437
438         if ((c < 0x80) || ((c > 0xa0) && (c < 0xe0))) {
439                 /* 7-bit */
440                 *wc = c;
441                 return (1);
442         }
443
444         if (n < 2) {
445                 werr("incomplete character sequence (%s)", show_mb(mb));
446                 return (-1);
447         }
448
449         /* Store both bytes as a single 16-bit wide. */
450         c <<= 8;
451         c |= (uint8_t)(mb[1]);
452         *wc = c;
453         return (2);
454 }
455
456 /*
457  * EUC forms.  EUC encodings are "variable".  FreeBSD carries some additional
458  * variable data to encode these, but we're going to treat each as independent
459  * instead.  Its the only way we can sensibly move forward.
460  *
461  * Note that the way in which the different EUC forms vary is how wide
462  * CS2 and CS3 are and what the first byte of them is.
463  */
464 static int
465 towide_euc_impl(wchar_t *wc, const char *mb, unsigned n,
466     uint8_t cs2, uint8_t cs2width, uint8_t cs3, uint8_t cs3width)
467 {
468         int i;
469         int width = 2;
470         wchar_t c;
471
472         c = *(uint8_t *)mb;
473
474         /*
475          * All variations of EUC encode 7-bit ASCII as one byte, and use
476          * additional bytes for more than that.
477          */
478         if ((c & 0x80) == 0) {
479                 /* 7-bit */
480                 *wc = c;
481                 return (1);
482         }
483
484         /*
485          * All EUC variants reserve 0xa1-0xff to identify CS1, which
486          * is always two bytes wide.  Note that unused CS will be zero,
487          * and that cannot be true because we know that the high order
488          * bit must be set.
489          */
490         if (c >= 0xa1) {
491                 width = 2;
492         } else if (c == cs2) {
493                 width = cs2width;
494         } else if (c == cs3) {
495                 width = cs3width;
496         }
497
498         if ((int)n < width) {
499                 werr("incomplete character sequence (%s)", show_mb(mb));
500                 return (-1);
501         }
502
503         for (i = 1; i < width; i++) {
504                 /* pull in the next byte */
505                 c <<= 8;
506                 c |= (uint8_t)(mb[i]);
507         }
508
509         *wc = c;
510         return (width);
511 }
512
513 #pragma GCC diagnostic pop
514
515 /*
516  * EUC-CN encodes as follows:
517  *
518  * Code set 0 (ASCII):                          0x21-0x7E
519  * Code set 1 (CNS 11643-1992 Plane 1):         0xA1A1-0xFEFE
520  * Code set 2:                                  unused
521  * Code set 3:                                  unused
522  */
523 int
524 towide_euccn(wchar_t *wc, const char *mb, unsigned n)
525 {
526         return (towide_euc_impl(wc, mb, n, 0x8e, 4, 0, 0));
527 }
528
529 /*
530  * EUC-JP encodes as follows:
531  *
532  * Code set 0 (ASCII or JIS X 0201-1976 Roman): 0x21-0x7E
533  * Code set 1 (JIS X 0208):                     0xA1A1-0xFEFE
534  * Code set 2 (half-width katakana):            0x8EA1-0x8EDF
535  * Code set 3 (JIS X 0212-1990):                0x8FA1A1-0x8FFEFE
536  */
537 int
538 towide_eucjp(wchar_t *wc, const char *mb, unsigned n)
539 {
540         return (towide_euc_impl(wc, mb, n, 0x8e, 2, 0x8f, 3));
541 }
542
543 /*
544  * EUC-KR encodes as follows:
545  *
546  * Code set 0 (ASCII or KS C 5636-1993):        0x21-0x7E
547  * Code set 1 (KS C 5601-1992):                 0xA1A1-0xFEFE
548  * Code set 2:                                  unused
549  * Code set 3:                                  unused
550  */
551 int
552 towide_euckr(wchar_t *wc, const char *mb, unsigned n)
553 {
554         return (towide_euc_impl(wc, mb, n, 0, 0, 0, 0));
555 }
556
557 /*
558  * EUC-TW encodes as follows:
559  *
560  * Code set 0 (ASCII):                          0x21-0x7E
561  * Code set 1 (CNS 11643-1992 Plane 1):         0xA1A1-0xFEFE
562  * Code set 2 (CNS 11643-1992 Planes 1-16):     0x8EA1A1A1-0x8EB0FEFE
563  * Code set 3:                                  unused
564  */
565 int
566 towide_euctw(wchar_t *wc, const char *mb, unsigned n)
567 {
568         return (towide_euc_impl(wc, mb, n, 0x8e, 4, 0, 0));
569 }
570
571 /*
572  * Public entry points.
573  */
574
575 int
576 to_wide(wchar_t *wc, const char *mb)
577 {
578         /* this won't fail hard */
579         return (_towide(wc, mb, strlen(mb)));
580 }
581
582 int
583 to_mb(char *mb, wchar_t wc)
584 {
585         int     rv;
586
587         if ((rv = _tomb(mb, wc)) < 0) {
588                 errf(widemsg);
589                 free(widemsg);
590                 widemsg = NULL;
591         }
592         return (rv);
593 }
594
595 char *
596 to_mb_string(const wchar_t *wcs)
597 {
598         char    *mbs;
599         char    *ptr;
600         int     len;
601
602         mbs = malloc((wcslen(wcs) * mb_cur_max) + 1);
603         if (mbs == NULL) {
604                 errf("out of memory");
605                 return (NULL);
606         }
607         ptr = mbs;
608         while (*wcs) {
609                 if ((len = to_mb(ptr, *wcs)) < 0) {
610                         INTERR;
611                         free(mbs);
612                         return (NULL);
613                 }
614                 wcs++;
615                 ptr += len;
616         }
617         *ptr = 0;
618         return (mbs);
619 }
620
621 void
622 set_wide_encoding(const char *encoding)
623 {
624         int i;
625
626         _towide = towide_none;
627         _tomb = tomb_none;
628         _encoding = "NONE";
629         _nbits = 8;
630
631         for (i = 0; mb_encodings[i].name; i++) {
632                 if (strcasecmp(encoding, mb_encodings[i].name) == 0) {
633                         _towide = mb_encodings[i].towide;
634                         _tomb = mb_encodings[i].tomb;
635                         _encoding = mb_encodings[i].cname;
636                         _nbits = mb_encodings[i].nbits;
637                         break;
638                 }
639         }
640 }
641
642 const char *
643 get_wide_encoding(void)
644 {
645         return (_encoding);
646 }
647
648 int
649 max_wide(void)
650 {
651         return ((int)((1U << _nbits) - 1));
652 }