162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *   Some of the source code in this file came from fs/cifs/uniupr.h
462306a36Sopenharmony_ci *   Copyright (c) International Business Machines  Corp., 2000,2002
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci *   Some of the source code in this file came from fs/cifs/cifs_unicode.c
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci *   Copyright (c) International Business Machines  Corp., 2000,2009
962306a36Sopenharmony_ci *   Modified by Steve French (sfrench@us.ibm.com)
1062306a36Sopenharmony_ci *   Modified by Namjae Jeon (linkinjeon@kernel.org)
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci */
1362306a36Sopenharmony_ci#include <linux/fs.h>
1462306a36Sopenharmony_ci#include <linux/module.h>
1562306a36Sopenharmony_ci#include <linux/slab.h>
1662306a36Sopenharmony_ci#include <asm/unaligned.h>
1762306a36Sopenharmony_ci#include "nls_ucs2_utils.h"
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ciMODULE_LICENSE("GPL");
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/*
2262306a36Sopenharmony_ci * Latin upper case
2362306a36Sopenharmony_ci */
2462306a36Sopenharmony_cisigned char NlsUniUpperTable[512] = {
2562306a36Sopenharmony_ci	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 000-00f */
2662306a36Sopenharmony_ci	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 010-01f */
2762306a36Sopenharmony_ci	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 020-02f */
2862306a36Sopenharmony_ci	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 030-03f */
2962306a36Sopenharmony_ci	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 040-04f */
3062306a36Sopenharmony_ci	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 050-05f */
3162306a36Sopenharmony_ci	0, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
3262306a36Sopenharmony_ci				-32, -32, -32, -32, -32,	/* 060-06f */
3362306a36Sopenharmony_ci	-32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
3462306a36Sopenharmony_ci				-32, 0, 0, 0, 0, 0,	/* 070-07f */
3562306a36Sopenharmony_ci	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 080-08f */
3662306a36Sopenharmony_ci	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 090-09f */
3762306a36Sopenharmony_ci	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0a0-0af */
3862306a36Sopenharmony_ci	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0b0-0bf */
3962306a36Sopenharmony_ci	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0c0-0cf */
4062306a36Sopenharmony_ci	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0d0-0df */
4162306a36Sopenharmony_ci	-32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
4262306a36Sopenharmony_ci			 -32, -32, -32, -32, -32, -32,	/* 0e0-0ef */
4362306a36Sopenharmony_ci	-32, -32, -32, -32, -32, -32, -32, 0, -32, -32,
4462306a36Sopenharmony_ci			 -32, -32, -32, -32, -32, 121,	/* 0f0-0ff */
4562306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 100-10f */
4662306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 110-11f */
4762306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 120-12f */
4862306a36Sopenharmony_ci	0, 0, 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0, -1, 0,	/* 130-13f */
4962306a36Sopenharmony_ci	-1, 0, -1, 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0, -1,	/* 140-14f */
5062306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 150-15f */
5162306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 160-16f */
5262306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0, -1, 0,	/* 170-17f */
5362306a36Sopenharmony_ci	0, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0,	/* 180-18f */
5462306a36Sopenharmony_ci	0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0,	/* 190-19f */
5562306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0,	/* 1a0-1af */
5662306a36Sopenharmony_ci	-1, 0, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0,	/* 1b0-1bf */
5762306a36Sopenharmony_ci	0, 0, 0, 0, 0, -1, -2, 0, -1, -2, 0, -1, -2, 0, -1, 0,	/* 1c0-1cf */
5862306a36Sopenharmony_ci	-1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -79, 0, -1, /* 1d0-1df */
5962306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 1e0-1ef */
6062306a36Sopenharmony_ci	0, 0, -1, -2, 0, -1, 0, 0, 0, -1, 0, -1, 0, -1, 0, -1,	/* 1f0-1ff */
6162306a36Sopenharmony_ci};
6262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(NlsUniUpperTable);
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci/* Upper case range - Greek */
6562306a36Sopenharmony_cistatic signed char UniCaseRangeU03a0[47] = {
6662306a36Sopenharmony_ci	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -38, -37, -37, -37,	/* 3a0-3af */
6762306a36Sopenharmony_ci	0, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
6862306a36Sopenharmony_ci					 -32, -32, -32, -32,	/* 3b0-3bf */
6962306a36Sopenharmony_ci	-32, -32, -31, -32, -32, -32, -32, -32, -32, -32, -32, -32, -64,
7062306a36Sopenharmony_ci	-63, -63,
7162306a36Sopenharmony_ci};
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci/* Upper case range - Cyrillic */
7462306a36Sopenharmony_cistatic signed char UniCaseRangeU0430[48] = {
7562306a36Sopenharmony_ci	-32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
7662306a36Sopenharmony_ci					 -32, -32, -32, -32,	/* 430-43f */
7762306a36Sopenharmony_ci	-32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
7862306a36Sopenharmony_ci					 -32, -32, -32, -32,	/* 440-44f */
7962306a36Sopenharmony_ci	0, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
8062306a36Sopenharmony_ci					 -80, -80, 0, -80, -80,	/* 450-45f */
8162306a36Sopenharmony_ci};
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci/* Upper case range - Extended cyrillic */
8462306a36Sopenharmony_cistatic signed char UniCaseRangeU0490[61] = {
8562306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 490-49f */
8662306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 4a0-4af */
8762306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 4b0-4bf */
8862306a36Sopenharmony_ci	0, 0, -1, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1,
8962306a36Sopenharmony_ci};
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci/* Upper case range - Extended latin and greek */
9262306a36Sopenharmony_cistatic signed char UniCaseRangeU1e00[509] = {
9362306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 1e00-1e0f */
9462306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 1e10-1e1f */
9562306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 1e20-1e2f */
9662306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 1e30-1e3f */
9762306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 1e40-1e4f */
9862306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 1e50-1e5f */
9962306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 1e60-1e6f */
10062306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 1e70-1e7f */
10162306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 1e80-1e8f */
10262306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, 0, 0, 0, 0, -59, 0, -1, 0, -1,	/* 1e90-1e9f */
10362306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 1ea0-1eaf */
10462306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 1eb0-1ebf */
10562306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 1ec0-1ecf */
10662306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 1ed0-1edf */
10762306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,	/* 1ee0-1eef */
10862306a36Sopenharmony_ci	0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0,	/* 1ef0-1eff */
10962306a36Sopenharmony_ci	8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0,	/* 1f00-1f0f */
11062306a36Sopenharmony_ci	8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 1f10-1f1f */
11162306a36Sopenharmony_ci	8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0,	/* 1f20-1f2f */
11262306a36Sopenharmony_ci	8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0,	/* 1f30-1f3f */
11362306a36Sopenharmony_ci	8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 1f40-1f4f */
11462306a36Sopenharmony_ci	0, 8, 0, 8, 0, 8, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,	/* 1f50-1f5f */
11562306a36Sopenharmony_ci	8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0,	/* 1f60-1f6f */
11662306a36Sopenharmony_ci	74, 74, 86, 86, 86, 86, 100, 100, 0, 0, 112, 112,
11762306a36Sopenharmony_ci				 126, 126, 0, 0,	/* 1f70-1f7f */
11862306a36Sopenharmony_ci	8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0,	/* 1f80-1f8f */
11962306a36Sopenharmony_ci	8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0,	/* 1f90-1f9f */
12062306a36Sopenharmony_ci	8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0,	/* 1fa0-1faf */
12162306a36Sopenharmony_ci	8, 8, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 1fb0-1fbf */
12262306a36Sopenharmony_ci	0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 1fc0-1fcf */
12362306a36Sopenharmony_ci	8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 1fd0-1fdf */
12462306a36Sopenharmony_ci	8, 8, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 1fe0-1fef */
12562306a36Sopenharmony_ci	0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12662306a36Sopenharmony_ci};
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci/* Upper case range - Wide latin */
12962306a36Sopenharmony_cistatic signed char UniCaseRangeUff40[27] = {
13062306a36Sopenharmony_ci	0, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
13162306a36Sopenharmony_ci			 -32, -32, -32, -32, -32,	/* ff40-ff4f */
13262306a36Sopenharmony_ci	-32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
13362306a36Sopenharmony_ci};
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci/*
13662306a36Sopenharmony_ci * Upper Case Range
13762306a36Sopenharmony_ci */
13862306a36Sopenharmony_ciconst struct UniCaseRange NlsUniUpperRange[] = {
13962306a36Sopenharmony_ci	{0x03a0, 0x03ce, UniCaseRangeU03a0},
14062306a36Sopenharmony_ci	{0x0430, 0x045f, UniCaseRangeU0430},
14162306a36Sopenharmony_ci	{0x0490, 0x04cc, UniCaseRangeU0490},
14262306a36Sopenharmony_ci	{0x1e00, 0x1ffc, UniCaseRangeU1e00},
14362306a36Sopenharmony_ci	{0xff40, 0xff5a, UniCaseRangeUff40},
14462306a36Sopenharmony_ci	{0}
14562306a36Sopenharmony_ci};
14662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(NlsUniUpperRange);
147