1 /* SPDX-License-Identifier: GPL-2.0 */
2 #include <linux/module.h>
3 #include <linux/kernel.h>
4 #include <linux/string.h>
5 #include <linux/slab.h>
6 #include <linux/parser.h>
7 #include <linux/errno.h>
8 #include <linux/unicode.h>
12 int utf8_validate(const struct unicode_map *um, const struct qstr *str)
14 const struct utf8data *data = utf8nfdi(um->version);
16 if (utf8nlen(data, str->name, str->len) < 0)
20 EXPORT_SYMBOL(utf8_validate);
22 int utf8_strncmp(const struct unicode_map *um,
23 const struct qstr *s1, const struct qstr *s2)
25 const struct utf8data *data = utf8nfdi(um->version);
26 struct utf8cursor cur1, cur2;
29 if (utf8ncursor(&cur1, data, s1->name, s1->len) < 0)
32 if (utf8ncursor(&cur2, data, s2->name, s2->len) < 0)
47 EXPORT_SYMBOL(utf8_strncmp);
49 int utf8_strncasecmp(const struct unicode_map *um,
50 const struct qstr *s1, const struct qstr *s2)
52 const struct utf8data *data = utf8nfdicf(um->version);
53 struct utf8cursor cur1, cur2;
56 if (utf8ncursor(&cur1, data, s1->name, s1->len) < 0)
59 if (utf8ncursor(&cur2, data, s2->name, s2->len) < 0)
74 EXPORT_SYMBOL(utf8_strncasecmp);
76 int utf8_casefold(const struct unicode_map *um, const struct qstr *str,
77 unsigned char *dest, size_t dlen)
79 const struct utf8data *data = utf8nfdicf(um->version);
80 struct utf8cursor cur;
83 if (utf8ncursor(&cur, data, str->name, str->len) < 0)
86 for (nlen = 0; nlen < dlen; nlen++) {
87 int c = utf8byte(&cur);
98 EXPORT_SYMBOL(utf8_casefold);
100 int utf8_normalize(const struct unicode_map *um, const struct qstr *str,
101 unsigned char *dest, size_t dlen)
103 const struct utf8data *data = utf8nfdi(um->version);
104 struct utf8cursor cur;
107 if (utf8ncursor(&cur, data, str->name, str->len) < 0)
110 for (nlen = 0; nlen < dlen; nlen++) {
111 int c = utf8byte(&cur);
122 EXPORT_SYMBOL(utf8_normalize);
124 static int utf8_parse_version(const char *version, unsigned int *maj,
125 unsigned int *min, unsigned int *rev)
128 char version_string[12];
129 const struct match_token token[] = {
134 strncpy(version_string, version, sizeof(version_string));
136 if (match_token(version_string, token, args) != 1)
139 if (match_int(&args[0], maj) || match_int(&args[1], min) ||
140 match_int(&args[2], rev))
146 struct unicode_map *utf8_load(const char *version)
148 struct unicode_map *um = NULL;
152 unsigned int maj, min, rev;
154 if (utf8_parse_version(version, &maj, &min, &rev) < 0)
155 return ERR_PTR(-EINVAL);
157 if (!utf8version_is_supported(maj, min, rev))
158 return ERR_PTR(-EINVAL);
160 unicode_version = UNICODE_AGE(maj, min, rev);
162 unicode_version = utf8version_latest();
163 printk(KERN_WARNING"UTF-8 version not specified. "
164 "Assuming latest supported version (%d.%d.%d).",
165 (unicode_version >> 16) & 0xff,
166 (unicode_version >> 8) & 0xff,
167 (unicode_version & 0xff));
170 um = kzalloc(sizeof(struct unicode_map), GFP_KERNEL);
172 return ERR_PTR(-ENOMEM);
174 um->charset = "UTF-8";
175 um->version = unicode_version;
179 EXPORT_SYMBOL(utf8_load);
181 void utf8_unload(struct unicode_map *um)
185 EXPORT_SYMBOL(utf8_unload);
187 MODULE_LICENSE("GPL v2");