2 * linux/fs/nls/nls_base.c
4 * Native language support--charsets and unicode translations.
5 * By Gordon Chaffee 1996, 1997
7 * Unicode based case conversion 1999 by Wolfram Pienkoss
11 #include <linux/module.h>
12 #include <linux/string.h>
13 #include <linux/nls.h>
14 #include <linux/kernel.h>
15 #include <linux/errno.h>
16 #include <linux/kmod.h>
17 #include <linux/spinlock.h>
18 #include <asm/byteorder.h>
20 static struct nls_table default_table;
21 static struct nls_table *tables = &default_table;
22 static DEFINE_SPINLOCK(nls_lock);
25 * Sample implementation from Unicode home page.
26 * http://www.stonehand.com/unicode/standard/fss-utf.html
36 static const struct utf8_table utf8_table[] =
38 {0x80, 0x00, 0*6, 0x7F, 0, /* 1 byte sequence */},
39 {0xE0, 0xC0, 1*6, 0x7FF, 0x80, /* 2 byte sequence */},
40 {0xF0, 0xE0, 2*6, 0xFFFF, 0x800, /* 3 byte sequence */},
41 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
42 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
43 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
44 {0, /* end of table */}
47 #define UNICODE_MAX 0x0010ffff
48 #define PLANE_SIZE 0x00010000
50 #define SURROGATE_MASK 0xfffff800
51 #define SURROGATE_PAIR 0x0000d800
52 #define SURROGATE_LOW 0x00000400
53 #define SURROGATE_BITS 0x000003ff
55 int utf8_to_utf32(const u8 *s, int inlen, unicode_t *pu)
59 const struct utf8_table *t;
64 for (t = utf8_table; t->cmask; t++) {
66 if ((c0 & t->cmask) == t->cval) {
68 if (l < t->lval || l > UNICODE_MAX ||
69 (l & SURROGATE_MASK) == SURROGATE_PAIR)
77 c = (*s ^ 0x80) & 0xFF;
84 EXPORT_SYMBOL(utf8_to_utf32);
86 int utf32_to_utf8(unicode_t u, u8 *s, int maxout)
90 const struct utf8_table *t;
96 if (l > UNICODE_MAX || (l & SURROGATE_MASK) == SURROGATE_PAIR)
100 for (t = utf8_table; t->cmask && maxout; t++, maxout--) {
104 *s = (u8) (t->cval | (l >> c));
108 *s = (u8) (0x80 | ((l >> c) & 0x3F));
115 EXPORT_SYMBOL(utf32_to_utf8);
117 static inline void put_utf16(wchar_t *s, unsigned c, enum utf16_endian endian)
123 case UTF16_LITTLE_ENDIAN:
124 *s = __cpu_to_le16(c);
126 case UTF16_BIG_ENDIAN:
127 *s = __cpu_to_be16(c);
132 int utf8s_to_utf16s(const u8 *s, int inlen, enum utf16_endian endian,
133 wchar_t *pwcs, int maxout)
140 while (inlen > 0 && maxout > 0 && *s) {
142 size = utf8_to_utf32(s, inlen, &u);
148 if (u >= PLANE_SIZE) {
152 put_utf16(op++, SURROGATE_PAIR |
153 ((u >> 10) & SURROGATE_BITS),
155 put_utf16(op++, SURROGATE_PAIR |
157 (u & SURROGATE_BITS),
161 put_utf16(op++, u, endian);
165 put_utf16(op++, *s++, endian);
172 EXPORT_SYMBOL(utf8s_to_utf16s);
174 static inline unsigned long get_utf16(unsigned c, enum utf16_endian endian)
179 case UTF16_LITTLE_ENDIAN:
180 return __le16_to_cpu(c);
181 case UTF16_BIG_ENDIAN:
182 return __be16_to_cpu(c);
186 int utf16s_to_utf8s(const wchar_t *pwcs, int inlen, enum utf16_endian endian,
194 while (inlen > 0 && maxout > 0) {
195 u = get_utf16(*pwcs, endian);
201 if ((u & SURROGATE_MASK) == SURROGATE_PAIR) {
202 if (u & SURROGATE_LOW) {
203 /* Ignore character and move on */
208 v = get_utf16(*pwcs, endian);
209 if ((v & SURROGATE_MASK) != SURROGATE_PAIR ||
210 !(v & SURROGATE_LOW)) {
211 /* Ignore character and move on */
214 u = PLANE_SIZE + ((u & SURROGATE_BITS) << 10)
215 + (v & SURROGATE_BITS);
219 size = utf32_to_utf8(u, op, maxout);
221 /* Ignore character and move on */
233 EXPORT_SYMBOL(utf16s_to_utf8s);
235 int __register_nls(struct nls_table *nls, struct module *owner)
237 struct nls_table ** tmp = &tables;
243 spin_lock(&nls_lock);
246 spin_unlock(&nls_lock);
253 spin_unlock(&nls_lock);
256 EXPORT_SYMBOL(__register_nls);
258 int unregister_nls(struct nls_table * nls)
260 struct nls_table ** tmp = &tables;
262 spin_lock(&nls_lock);
266 spin_unlock(&nls_lock);
271 spin_unlock(&nls_lock);
275 static struct nls_table *find_nls(char *charset)
277 struct nls_table *nls;
278 spin_lock(&nls_lock);
279 for (nls = tables; nls; nls = nls->next) {
280 if (!strcmp(nls->charset, charset))
282 if (nls->alias && !strcmp(nls->alias, charset))
285 if (nls && !try_module_get(nls->owner))
287 spin_unlock(&nls_lock);
291 struct nls_table *load_nls(char *charset)
293 return try_then_request_module(find_nls(charset), "nls_%s", charset);
296 void unload_nls(struct nls_table *nls)
299 module_put(nls->owner);
302 static const wchar_t charset2uni[256] = {
304 0x0000, 0x0001, 0x0002, 0x0003,
305 0x0004, 0x0005, 0x0006, 0x0007,
306 0x0008, 0x0009, 0x000a, 0x000b,
307 0x000c, 0x000d, 0x000e, 0x000f,
309 0x0010, 0x0011, 0x0012, 0x0013,
310 0x0014, 0x0015, 0x0016, 0x0017,
311 0x0018, 0x0019, 0x001a, 0x001b,
312 0x001c, 0x001d, 0x001e, 0x001f,
314 0x0020, 0x0021, 0x0022, 0x0023,
315 0x0024, 0x0025, 0x0026, 0x0027,
316 0x0028, 0x0029, 0x002a, 0x002b,
317 0x002c, 0x002d, 0x002e, 0x002f,
319 0x0030, 0x0031, 0x0032, 0x0033,
320 0x0034, 0x0035, 0x0036, 0x0037,
321 0x0038, 0x0039, 0x003a, 0x003b,
322 0x003c, 0x003d, 0x003e, 0x003f,
324 0x0040, 0x0041, 0x0042, 0x0043,
325 0x0044, 0x0045, 0x0046, 0x0047,
326 0x0048, 0x0049, 0x004a, 0x004b,
327 0x004c, 0x004d, 0x004e, 0x004f,
329 0x0050, 0x0051, 0x0052, 0x0053,
330 0x0054, 0x0055, 0x0056, 0x0057,
331 0x0058, 0x0059, 0x005a, 0x005b,
332 0x005c, 0x005d, 0x005e, 0x005f,
334 0x0060, 0x0061, 0x0062, 0x0063,
335 0x0064, 0x0065, 0x0066, 0x0067,
336 0x0068, 0x0069, 0x006a, 0x006b,
337 0x006c, 0x006d, 0x006e, 0x006f,
339 0x0070, 0x0071, 0x0072, 0x0073,
340 0x0074, 0x0075, 0x0076, 0x0077,
341 0x0078, 0x0079, 0x007a, 0x007b,
342 0x007c, 0x007d, 0x007e, 0x007f,
344 0x0080, 0x0081, 0x0082, 0x0083,
345 0x0084, 0x0085, 0x0086, 0x0087,
346 0x0088, 0x0089, 0x008a, 0x008b,
347 0x008c, 0x008d, 0x008e, 0x008f,
349 0x0090, 0x0091, 0x0092, 0x0093,
350 0x0094, 0x0095, 0x0096, 0x0097,
351 0x0098, 0x0099, 0x009a, 0x009b,
352 0x009c, 0x009d, 0x009e, 0x009f,
354 0x00a0, 0x00a1, 0x00a2, 0x00a3,
355 0x00a4, 0x00a5, 0x00a6, 0x00a7,
356 0x00a8, 0x00a9, 0x00aa, 0x00ab,
357 0x00ac, 0x00ad, 0x00ae, 0x00af,
359 0x00b0, 0x00b1, 0x00b2, 0x00b3,
360 0x00b4, 0x00b5, 0x00b6, 0x00b7,
361 0x00b8, 0x00b9, 0x00ba, 0x00bb,
362 0x00bc, 0x00bd, 0x00be, 0x00bf,
364 0x00c0, 0x00c1, 0x00c2, 0x00c3,
365 0x00c4, 0x00c5, 0x00c6, 0x00c7,
366 0x00c8, 0x00c9, 0x00ca, 0x00cb,
367 0x00cc, 0x00cd, 0x00ce, 0x00cf,
369 0x00d0, 0x00d1, 0x00d2, 0x00d3,
370 0x00d4, 0x00d5, 0x00d6, 0x00d7,
371 0x00d8, 0x00d9, 0x00da, 0x00db,
372 0x00dc, 0x00dd, 0x00de, 0x00df,
374 0x00e0, 0x00e1, 0x00e2, 0x00e3,
375 0x00e4, 0x00e5, 0x00e6, 0x00e7,
376 0x00e8, 0x00e9, 0x00ea, 0x00eb,
377 0x00ec, 0x00ed, 0x00ee, 0x00ef,
379 0x00f0, 0x00f1, 0x00f2, 0x00f3,
380 0x00f4, 0x00f5, 0x00f6, 0x00f7,
381 0x00f8, 0x00f9, 0x00fa, 0x00fb,
382 0x00fc, 0x00fd, 0x00fe, 0x00ff,
385 static const unsigned char page00[256] = {
386 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
387 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
388 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
389 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
390 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
391 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
392 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
393 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
394 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
395 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
396 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
397 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
398 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */
399 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */
400 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */
401 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
403 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */
404 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */
405 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */
406 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */
407 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */
408 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */
409 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */
410 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */
411 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */
412 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */
413 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */
414 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */
415 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */
416 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */
417 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */
418 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
421 static const unsigned char *const page_uni2charset[256] = {
425 static const unsigned char charset2lower[256] = {
426 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
427 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
428 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
429 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
430 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
431 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
432 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
433 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
434 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x40-0x47 */
435 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x48-0x4f */
436 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x50-0x57 */
437 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
438 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */
439 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */
440 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */
441 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
443 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */
444 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */
445 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */
446 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */
447 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */
448 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */
449 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */
450 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */
451 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */
452 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */
453 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */
454 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */
455 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */
456 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */
457 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */
458 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
461 static const unsigned char charset2upper[256] = {
462 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
463 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
464 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
465 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
466 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
467 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
468 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
469 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
470 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
471 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
472 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
473 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
474 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */
475 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */
476 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */
477 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
479 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */
480 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */
481 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */
482 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */
483 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */
484 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */
485 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */
486 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */
487 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */
488 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */
489 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */
490 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */
491 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */
492 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */
493 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */
494 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
498 static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
500 const unsigned char *uni2charset;
501 unsigned char cl = uni & 0x00ff;
502 unsigned char ch = (uni & 0xff00) >> 8;
505 return -ENAMETOOLONG;
507 uni2charset = page_uni2charset[ch];
508 if (uni2charset && uni2charset[cl])
509 out[0] = uni2charset[cl];
515 static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
517 *uni = charset2uni[*rawstring];
523 static struct nls_table default_table = {
524 .charset = "default",
525 .uni2char = uni2char,
526 .char2uni = char2uni,
527 .charset2lower = charset2lower,
528 .charset2upper = charset2upper,
531 /* Returns a simple default translation table */
532 struct nls_table *load_nls_default(void)
534 struct nls_table *default_nls;
536 default_nls = load_nls(CONFIG_NLS_DEFAULT);
537 if (default_nls != NULL)
540 return &default_table;
543 EXPORT_SYMBOL(unregister_nls);
544 EXPORT_SYMBOL(unload_nls);
545 EXPORT_SYMBOL(load_nls);
546 EXPORT_SYMBOL(load_nls_default);
548 MODULE_LICENSE("Dual BSD/GPL");