Branch
Hash :
91f96be0
Author :
Date :
2021-06-06T11:51:12
Change the license of the library from LGPL 2.0 to LGPL 2.1.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
/*
* Copyright (C) 1999-2002, 2005, 2016 Free Software Foundation, Inc.
* This file is part of the GNU LIBICONV Library.
*
* The GNU LIBICONV Library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* The GNU LIBICONV Library is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with the GNU LIBICONV Library; see the file COPYING.LIB.
* If not, see <https://www.gnu.org/licenses/>.
*/
/*
* CP932
*/
/*
* Microsoft CP932 is a slightly extended version of SHIFT_JIS.
* The differences between the EASTASIA/JIS/SHIFTJIS.TXT and the
* VENDORS/MICSFT/WINDOWS/CP932.TXT tables found on ftp.unicode.org are
* as follows:
*
* 1. CP932 uses ASCII, not JISX0201 Roman.
*
* 2. Some characters in the JISX0208 range are defined differently:
*
* code SHIFTJIS.TXT CP932.TXT
* 0x815F 0x005C # REVERSE SOLIDUS 0xFF3C # FULLWIDTH REVERSE SOLIDUS
* 0x8160 0x301C # WAVE DASH 0xFF5E # FULLWIDTH TILDE
* 0x8161 0x2016 # DOUBLE VERTICAL LINE 0x2225 # PARALLEL TO
* 0x817C 0x2212 # MINUS SIGN 0xFF0D # FULLWIDTH HYPHEN-MINUS
* 0x8191 0x00A2 # CENT SIGN 0xFFE0 # FULLWIDTH CENT SIGN
* 0x8192 0x00A3 # POUND SIGN 0xFFE1 # FULLWIDTH POUND SIGN
* 0x81CA 0x00AC # NOT SIGN 0xFFE2 # FULLWIDTH NOT SIGN
*
* We don't implement the latter 6 of these changes, only the first one.
* SHIFTJIS.TXT makes more sense. However, as a compromise with user
* expectation, we implement the middle 5 of these changes in the
* Unicode to CP932 direction. We don't implement the last one at all,
* because it would collide with the mapping of 0xFA54.
*
* 3. A few new rows. See cp932ext.h.
*
* Many variants of CP932 (in GNU libc, JDK, OSF/1, Windows-2000, ICU) also
* add:
*
* 4. Private area mappings:
*
* code Unicode
* 0x{F0..F9}{40..7E,80..FC} U+E000..U+E757
*
* We add them too because, although there are backward compatibility problems
* when a character from a private area is moved to an official Unicode code
* point, they are useful for some people in practice.
*/
#include "cp932ext.h"
/*
Conversion between SJIS codes (s1,s2) and JISX0208 codes (c1,c2):
Example. (s1,s2) = 0x8140, (c1,c2) = 0x2121.
0x81 <= s1 <= 0x9F || 0xE0 <= s1 <= 0xEA,
0x40 <= s2 <= 0x7E || 0x80 <= s2 <= 0xFC,
0x21 <= c1 <= 0x74, 0x21 <= c2 <= 0x7E.
Invariant:
94*2*(s1 < 0xE0 ? s1-0x81 : s1-0xC1) + (s2 < 0x80 ? s2-0x40 : s2-0x41)
= 94*(c1-0x21)+(c2-0x21)
Conversion (s1,s2) -> (c1,c2):
t1 := (s1 < 0xE0 ? s1-0x81 : s1-0xC1)
t2 := (s2 < 0x80 ? s2-0x40 : s2-0x41)
c1 := 2*t1 + (t2 < 0x5E ? 0 : 1) + 0x21
c2 := (t2 < 0x5E ? t2 : t2-0x5E) + 0x21
Conversion (c1,c2) -> (s1,s2):
t1 := (c1 - 0x21) >> 1
t2 := ((c1 - 0x21) & 1) * 0x5E + (c2 - 0x21)
s1 := (t1 < 0x1F ? t1+0x81 : t1+0xC1)
s2 := (t2 < 0x3F ? t2+0x40 : t2+0x41)
*/
static int
cp932_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
{
unsigned char c = *s;
if (c < 0x80)
return ascii_mbtowc(conv,pwc,s,n);
else if (c >= 0xa1 && c <= 0xdf)
return jisx0201_mbtowc(conv,pwc,s,n);
else {
unsigned char s1, s2;
s1 = c;
if ((s1 >= 0x81 && s1 <= 0x9f && s1 != 0x87) || (s1 >= 0xe0 && s1 <= 0xea)) {
if (n < 2)
return RET_TOOFEW(0);
s2 = s[1];
if ((s2 >= 0x40 && s2 <= 0x7e) || (s2 >= 0x80 && s2 <= 0xfc)) {
unsigned char t1 = (s1 < 0xe0 ? s1-0x81 : s1-0xc1);
unsigned char t2 = (s2 < 0x80 ? s2-0x40 : s2-0x41);
unsigned char buf[2];
buf[0] = 2*t1 + (t2 < 0x5e ? 0 : 1) + 0x21;
buf[1] = (t2 < 0x5e ? t2 : t2-0x5e) + 0x21;
return jisx0208_mbtowc(conv,pwc,buf,2);
}
} else if ((s1 == 0x87) || (s1 >= 0xed && s1 <= 0xee) || (s1 >= 0xfa)) {
if (n < 2)
return RET_TOOFEW(0);
return cp932ext_mbtowc(conv,pwc,s,2);
} else if (s1 >= 0xf0 && s1 <= 0xf9) {
/* User-defined range. See
* Ken Lunde's "CJKV Information Processing", table 4-66, p. 206. */
if (n < 2)
return RET_TOOFEW(0);
s2 = s[1];
if ((s2 >= 0x40 && s2 <= 0x7e) || (s2 >= 0x80 && s2 <= 0xfc)) {
*pwc = 0xe000 + 188*(s1 - 0xf0) + (s2 < 0x80 ? s2-0x40 : s2-0x41);
return 2;
}
}
return RET_ILSEQ;
}
}
static int
cp932_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, size_t n)
{
unsigned char buf[2];
int ret;
/* Try ASCII. */
ret = ascii_wctomb(conv,buf,wc,1);
if (ret != RET_ILUNI) {
unsigned char c;
if (ret != 1) abort();
c = buf[0];
if (c < 0x80) {
r[0] = c;
return 1;
}
}
/* Try JIS X 0201-1976 Katakana. */
ret = jisx0201_wctomb(conv,buf,wc,1);
if (ret != RET_ILUNI) {
unsigned char c;
if (ret != 1) abort();
c = buf[0];
if (c >= 0xa1 && c <= 0xdf) {
r[0] = c;
return 1;
}
}
/* Try JIS X 0208-1990. */
ret = jisx0208_wctomb(conv,buf,wc,2);
if (ret != RET_ILUNI) {
unsigned char c1, c2;
if (ret != 2) abort();
if (n < 2)
return RET_TOOSMALL;
c1 = buf[0];
c2 = buf[1];
if ((c1 >= 0x21 && c1 <= 0x74) && (c2 >= 0x21 && c2 <= 0x7e)) {
unsigned char t1 = (c1 - 0x21) >> 1;
unsigned char t2 = (((c1 - 0x21) & 1) ? 0x5e : 0) + (c2 - 0x21);
r[0] = (t1 < 0x1f ? t1+0x81 : t1+0xc1);
r[1] = (t2 < 0x3f ? t2+0x40 : t2+0x41);
return 2;
}
}
/* Try CP932 extensions. */
ret = cp932ext_wctomb(conv,buf,wc,2);
if (ret != RET_ILUNI) {
if (ret != 2) abort();
if (n < 2)
return RET_TOOSMALL;
r[0] = buf[0];
r[1] = buf[1];
return 2;
}
/* User-defined range. See
* Ken Lunde's "CJKV Information Processing", table 4-66, p. 206. */
if (wc >= 0xe000 && wc < 0xe758) {
unsigned char c1, c2;
if (n < 2)
return RET_TOOSMALL;
c1 = (unsigned int) (wc - 0xe000) / 188;
c2 = (unsigned int) (wc - 0xe000) % 188;
r[0] = c1+0xf0;
r[1] = (c2 < 0x3f ? c2+0x40 : c2+0x41);
return 2;
}
/* Irreversible mappings. */
if (wc == 0xff5e) {
if (n < 2)
return RET_TOOSMALL;
r[0] = 0x81;
r[1] = 0x60;
return 2;
}
if (wc == 0x2225) {
if (n < 2)
return RET_TOOSMALL;
r[0] = 0x81;
r[1] = 0x61;
return 2;
}
if (wc == 0xff0d) {
if (n < 2)
return RET_TOOSMALL;
r[0] = 0x81;
r[1] = 0x7c;
return 2;
}
if (wc == 0xffe0) {
if (n < 2)
return RET_TOOSMALL;
r[0] = 0x81;
r[1] = 0x91;
return 2;
}
if (wc == 0xffe1) {
if (n < 2)
return RET_TOOSMALL;
r[0] = 0x81;
r[1] = 0x92;
return 2;
}
return RET_ILUNI;
}