1
2
3
4
5
6
7
8
9
10
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>
19
20static struct nls_table default_table;
21static struct nls_table *tables = &default_table;
22static DEFINE_SPINLOCK(nls_lock);
23
24
25
26
27
28struct utf8_table {
29 int cmask;
30 int cval;
31 int shift;
32 long lmask;
33 long lval;
34};
35
36static const struct utf8_table utf8_table[] =
37{
38 {0x80, 0x00, 0*6, 0x7F, 0, },
39 {0xE0, 0xC0, 1*6, 0x7FF, 0x80, },
40 {0xF0, 0xE0, 2*6, 0xFFFF, 0x800, },
41 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, },
42 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, },
43 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, },
44 {0, }
45};
46
47#define UNICODE_MAX 0x0010ffff
48#define PLANE_SIZE 0x00010000
49
50#define SURROGATE_MASK 0xfffff800
51#define SURROGATE_PAIR 0x0000d800
52#define SURROGATE_LOW 0x00000400
53#define SURROGATE_BITS 0x000003ff
54
55int utf8_to_utf32(const u8 *s, int inlen, unicode_t *pu)
56{
57 unsigned long l;
58 int c0, c, nc;
59 const struct utf8_table *t;
60
61 nc = 0;
62 c0 = *s;
63 l = c0;
64 for (t = utf8_table; t->cmask; t++) {
65 nc++;
66 if ((c0 & t->cmask) == t->cval) {
67 l &= t->lmask;
68 if (l < t->lval || l > UNICODE_MAX ||
69 (l & SURROGATE_MASK) == SURROGATE_PAIR)
70 return -1;
71 *pu = (unicode_t) l;
72 return nc;
73 }
74 if (inlen <= nc)
75 return -1;
76 s++;
77 c = (*s ^ 0x80) & 0xFF;
78 if (c & 0xC0)
79 return -1;
80 l = (l << 6) | c;
81 }
82 return -1;
83}
84EXPORT_SYMBOL(utf8_to_utf32);
85
86int utf32_to_utf8(unicode_t u, u8 *s, int maxout)
87{
88 unsigned long l;
89 int c, nc;
90 const struct utf8_table *t;
91
92 if (!s)
93 return 0;
94
95 l = u;
96 if (l > UNICODE_MAX || (l & SURROGATE_MASK) == SURROGATE_PAIR)
97 return -1;
98
99 nc = 0;
100 for (t = utf8_table; t->cmask && maxout; t++, maxout--) {
101 nc++;
102 if (l <= t->lmask) {
103 c = t->shift;
104 *s = (u8) (t->cval | (l >> c));
105 while (c > 0) {
106 c -= 6;
107 s++;
108 *s = (u8) (0x80 | ((l >> c) & 0x3F));
109 }
110 return nc;
111 }
112 }
113 return -1;
114}
115EXPORT_SYMBOL(utf32_to_utf8);
116
117static inline void put_utf16(wchar_t *s, unsigned c, enum utf16_endian endian)
118{
119 switch (endian) {
120 default:
121 *s = (wchar_t) c;
122 break;
123 case UTF16_LITTLE_ENDIAN:
124 *s = __cpu_to_le16(c);
125 break;
126 case UTF16_BIG_ENDIAN:
127 *s = __cpu_to_be16(c);
128 break;
129 }
130}
131
132int utf8s_to_utf16s(const u8 *s, int inlen, enum utf16_endian endian,
133 wchar_t *pwcs, int maxout)
134{
135 u16 *op;
136 int size;
137 unicode_t u;
138
139 op = pwcs;
140 while (inlen > 0 && maxout > 0 && *s) {
141 if (*s & 0x80) {
142 size = utf8_to_utf32(s, inlen, &u);
143 if (size < 0)
144 return -EINVAL;
145 s += size;
146 inlen -= size;
147
148 if (u >= PLANE_SIZE) {
149 if (maxout < 2)
150 break;
151 u -= PLANE_SIZE;
152 put_utf16(op++, SURROGATE_PAIR |
153 ((u >> 10) & SURROGATE_BITS),
154 endian);
155 put_utf16(op++, SURROGATE_PAIR |
156 SURROGATE_LOW |
157 (u & SURROGATE_BITS),
158 endian);
159 maxout -= 2;
160 } else {
161 put_utf16(op++, u, endian);
162 maxout--;
163 }
164 } else {
165 put_utf16(op++, *s++, endian);
166 inlen--;
167 maxout--;
168 }
169 }
170 return op - pwcs;
171}
172EXPORT_SYMBOL(utf8s_to_utf16s);
173
174static inline unsigned long get_utf16(unsigned c, enum utf16_endian endian)
175{
176 switch (endian) {
177 default:
178 return c;
179 case UTF16_LITTLE_ENDIAN:
180 return __le16_to_cpu(c);
181 case UTF16_BIG_ENDIAN:
182 return __be16_to_cpu(c);
183 }
184}
185
186int utf16s_to_utf8s(const wchar_t *pwcs, int inlen, enum utf16_endian endian,
187 u8 *s, int maxout)
188{
189 u8 *op;
190 int size;
191 unsigned long u, v;
192
193 op = s;
194 while (inlen > 0 && maxout > 0) {
195 u = get_utf16(*pwcs, endian);
196 if (!u)
197 break;
198 pwcs++;
199 inlen--;
200 if (u > 0x7f) {
201 if ((u & SURROGATE_MASK) == SURROGATE_PAIR) {
202 if (u & SURROGATE_LOW) {
203
204 continue;
205 }
206 if (inlen <= 0)
207 break;
208 v = get_utf16(*pwcs, endian);
209 if ((v & SURROGATE_MASK) != SURROGATE_PAIR ||
210 !(v & SURROGATE_LOW)) {
211
212 continue;
213 }
214 u = PLANE_SIZE + ((u & SURROGATE_BITS) << 10)
215 + (v & SURROGATE_BITS);
216 pwcs++;
217 inlen--;
218 }
219 size = utf32_to_utf8(u, op, maxout);
220 if (size == -1) {
221
222 } else {
223 op += size;
224 maxout -= size;
225 }
226 } else {
227 *op++ = (u8) u;
228 maxout--;
229 }
230 }
231 return op - s;
232}
233EXPORT_SYMBOL(utf16s_to_utf8s);
234
235int __register_nls(struct nls_table *nls, struct module *owner)
236{
237 struct nls_table ** tmp = &tables;
238
239 if (nls->next)
240 return -EBUSY;
241
242 nls->owner = owner;
243 spin_lock(&nls_lock);
244 while (*tmp) {
245 if (nls == *tmp) {
246 spin_unlock(&nls_lock);
247 return -EBUSY;
248 }
249 tmp = &(*tmp)->next;
250 }
251 nls->next = tables;
252 tables = nls;
253 spin_unlock(&nls_lock);
254 return 0;
255}
256EXPORT_SYMBOL(__register_nls);
257
258int unregister_nls(struct nls_table * nls)
259{
260 struct nls_table ** tmp = &tables;
261
262 spin_lock(&nls_lock);
263 while (*tmp) {
264 if (nls == *tmp) {
265 *tmp = nls->next;
266 spin_unlock(&nls_lock);
267 return 0;
268 }
269 tmp = &(*tmp)->next;
270 }
271 spin_unlock(&nls_lock);
272 return -EINVAL;
273}
274
275static struct nls_table *find_nls(char *charset)
276{
277 struct nls_table *nls;
278 spin_lock(&nls_lock);
279 for (nls = tables; nls; nls = nls->next) {
280 if (!strcmp(nls->charset, charset))
281 break;
282 if (nls->alias && !strcmp(nls->alias, charset))
283 break;
284 }
285 if (nls && !try_module_get(nls->owner))
286 nls = NULL;
287 spin_unlock(&nls_lock);
288 return nls;
289}
290
291struct nls_table *load_nls(char *charset)
292{
293 return try_then_request_module(find_nls(charset), "nls_%s", charset);
294}
295
296void unload_nls(struct nls_table *nls)
297{
298 if (nls)
299 module_put(nls->owner);
300}
301
302static const wchar_t charset2uni[256] = {
303
304 0x0000, 0x0001, 0x0002, 0x0003,
305 0x0004, 0x0005, 0x0006, 0x0007,
306 0x0008, 0x0009, 0x000a, 0x000b,
307 0x000c, 0x000d, 0x000e, 0x000f,
308
309 0x0010, 0x0011, 0x0012, 0x0013,
310 0x0014, 0x0015, 0x0016, 0x0017,
311 0x0018, 0x0019, 0x001a, 0x001b,
312 0x001c, 0x001d, 0x001e, 0x001f,
313
314 0x0020, 0x0021, 0x0022, 0x0023,
315 0x0024, 0x0025, 0x0026, 0x0027,
316 0x0028, 0x0029, 0x002a, 0x002b,
317 0x002c, 0x002d, 0x002e, 0x002f,
318
319 0x0030, 0x0031, 0x0032, 0x0033,
320 0x0034, 0x0035, 0x0036, 0x0037,
321 0x0038, 0x0039, 0x003a, 0x003b,
322 0x003c, 0x003d, 0x003e, 0x003f,
323
324 0x0040, 0x0041, 0x0042, 0x0043,
325 0x0044, 0x0045, 0x0046, 0x0047,
326 0x0048, 0x0049, 0x004a, 0x004b,
327 0x004c, 0x004d, 0x004e, 0x004f,
328
329 0x0050, 0x0051, 0x0052, 0x0053,
330 0x0054, 0x0055, 0x0056, 0x0057,
331 0x0058, 0x0059, 0x005a, 0x005b,
332 0x005c, 0x005d, 0x005e, 0x005f,
333
334 0x0060, 0x0061, 0x0062, 0x0063,
335 0x0064, 0x0065, 0x0066, 0x0067,
336 0x0068, 0x0069, 0x006a, 0x006b,
337 0x006c, 0x006d, 0x006e, 0x006f,
338
339 0x0070, 0x0071, 0x0072, 0x0073,
340 0x0074, 0x0075, 0x0076, 0x0077,
341 0x0078, 0x0079, 0x007a, 0x007b,
342 0x007c, 0x007d, 0x007e, 0x007f,
343
344 0x0080, 0x0081, 0x0082, 0x0083,
345 0x0084, 0x0085, 0x0086, 0x0087,
346 0x0088, 0x0089, 0x008a, 0x008b,
347 0x008c, 0x008d, 0x008e, 0x008f,
348
349 0x0090, 0x0091, 0x0092, 0x0093,
350 0x0094, 0x0095, 0x0096, 0x0097,
351 0x0098, 0x0099, 0x009a, 0x009b,
352 0x009c, 0x009d, 0x009e, 0x009f,
353
354 0x00a0, 0x00a1, 0x00a2, 0x00a3,
355 0x00a4, 0x00a5, 0x00a6, 0x00a7,
356 0x00a8, 0x00a9, 0x00aa, 0x00ab,
357 0x00ac, 0x00ad, 0x00ae, 0x00af,
358
359 0x00b0, 0x00b1, 0x00b2, 0x00b3,
360 0x00b4, 0x00b5, 0x00b6, 0x00b7,
361 0x00b8, 0x00b9, 0x00ba, 0x00bb,
362 0x00bc, 0x00bd, 0x00be, 0x00bf,
363
364 0x00c0, 0x00c1, 0x00c2, 0x00c3,
365 0x00c4, 0x00c5, 0x00c6, 0x00c7,
366 0x00c8, 0x00c9, 0x00ca, 0x00cb,
367 0x00cc, 0x00cd, 0x00ce, 0x00cf,
368
369 0x00d0, 0x00d1, 0x00d2, 0x00d3,
370 0x00d4, 0x00d5, 0x00d6, 0x00d7,
371 0x00d8, 0x00d9, 0x00da, 0x00db,
372 0x00dc, 0x00dd, 0x00de, 0x00df,
373
374 0x00e0, 0x00e1, 0x00e2, 0x00e3,
375 0x00e4, 0x00e5, 0x00e6, 0x00e7,
376 0x00e8, 0x00e9, 0x00ea, 0x00eb,
377 0x00ec, 0x00ed, 0x00ee, 0x00ef,
378
379 0x00f0, 0x00f1, 0x00f2, 0x00f3,
380 0x00f4, 0x00f5, 0x00f6, 0x00f7,
381 0x00f8, 0x00f9, 0x00fa, 0x00fb,
382 0x00fc, 0x00fd, 0x00fe, 0x00ff,
383};
384
385static const unsigned char page00[256] = {
386 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
387 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
388 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
389 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
390 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
391 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
392 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
393 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
394 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
395 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
396 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
397 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
398 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
399 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
400 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
401 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
402
403 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
404 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
405 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
406 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
407 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
408 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
409 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
410 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
411 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
412 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
413 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
414 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
415 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
416 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
417 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
418 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
419};
420
421static const unsigned char *const page_uni2charset[256] = {
422 page00
423};
424
425static const unsigned char charset2lower[256] = {
426 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
427 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
428 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
429 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
430 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
431 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
432 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
433 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
434 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
435 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
436 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
437 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
438 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
439 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
440 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
441 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
442
443 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
444 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
445 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
446 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
447 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
448 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
449 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
450 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
451 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
452 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
453 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
454 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
455 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
456 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
457 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
458 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
459};
460
461static const unsigned char charset2upper[256] = {
462 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
463 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
464 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
465 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
466 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
467 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
468 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
469 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
470 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
471 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
472 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
473 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
474 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
475 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
476 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
477 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
478
479 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
480 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
481 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
482 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
483 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
484 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
485 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
486 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
487 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
488 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
489 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
490 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
491 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
492 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
493 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
494 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
495};
496
497
498static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
499{
500 const unsigned char *uni2charset;
501 unsigned char cl = uni & 0x00ff;
502 unsigned char ch = (uni & 0xff00) >> 8;
503
504 if (boundlen <= 0)
505 return -ENAMETOOLONG;
506
507 uni2charset = page_uni2charset[ch];
508 if (uni2charset && uni2charset[cl])
509 out[0] = uni2charset[cl];
510 else
511 return -EINVAL;
512 return 1;
513}
514
515static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
516{
517 *uni = charset2uni[*rawstring];
518 if (*uni == 0x0000)
519 return -EINVAL;
520 return 1;
521}
522
523static struct nls_table default_table = {
524 .charset = "default",
525 .uni2char = uni2char,
526 .char2uni = char2uni,
527 .charset2lower = charset2lower,
528 .charset2upper = charset2upper,
529};
530
531
532struct nls_table *load_nls_default(void)
533{
534 struct nls_table *default_nls;
535
536 default_nls = load_nls(CONFIG_NLS_DEFAULT);
537 if (default_nls != NULL)
538 return default_nls;
539 else
540 return &default_table;
541}
542
543EXPORT_SYMBOL(unregister_nls);
544EXPORT_SYMBOL(unload_nls);
545EXPORT_SYMBOL(load_nls);
546EXPORT_SYMBOL(load_nls_default);
547
548MODULE_LICENSE("Dual BSD/GPL");
549