Skip to content

Commit 01612e7

Browse files
committed
Update big5hkscs codec to conform to the HKSCS:2004 revision.
1 parent 27d3394 commit 01612e7

6 files changed

Lines changed: 1893 additions & 1802 deletions

File tree

Lib/test/cjkencodings_test.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,10 @@
6464
"\xab\x96\xe7\x9a\x84\xe5\x95\x8f\xe9\xa1\x8c\xe5\xb0\xb1\xe6\x98"
6565
"\xaf\x3a\x0a\x0a"),
6666
'big5hkscs': (
67-
"\x88\x45\x88\x5c\x8a\x73\x8b\xda\x8d\xd8\x0a",
68-
"\xf0\xa0\x84\x8c\xc4\x9a\xe9\xb5\xae\xe7\xbd\x93\xe6\xb4\x86\x0a"),
67+
"\x88\x45\x88\x5c\x8a\x73\x8b\xda\x8d\xd8\x0a\x88\x66\x88\x62\x88"
68+
"\xa7\x20\x88\xa7\x88\xa3\x0a",
69+
"\xf0\xa0\x84\x8c\xc4\x9a\xe9\xb5\xae\xe7\xbd\x93\xe6\xb4\x86\x0a"
70+
"\xc3\x8a\xc3\x8a\xcc\x84\xc3\xaa\x20\xc3\xaa\xc3\xaa\xcc\x84\x0a"),
6971
'cp949': (
7072
"\x8c\x63\xb9\xe6\xb0\xa2\xc7\xcf\x20\xbc\x84\xbd\xc3\xc4\xdd\xb6"
7173
"\xf3\x0a\x0a\xa8\xc0\xa8\xc0\xb3\xb3\x21\x21\x20\xec\xd7\xce\xfa"

Lib/test/test_codecmaps_hk.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@
1111
class TestBig5HKSCSMap(test_multibytecodec_support.TestBase_Mapping,
1212
unittest.TestCase):
1313
encoding = 'big5hkscs'
14-
mapfileurl = 'http://people.freebsd.org/~perky/i18n/BIG5HKSCS.TXT'
14+
mapfileurl = 'http://people.freebsd.org/~perky/i18n/BIG5HKSCS-2004.TXT'
1515

1616
def test_main():
1717
test_support.run_unittest(__name__)
1818

1919
if __name__ == "__main__":
20+
test_support.use_resources = ['urlfetch']
2021
test_main()

Lib/test/test_multibytecodec_support.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,17 @@ def test_mapping_supplemental(self):
323323

324324
def _testpoint(self, csetch, unich):
325325
if (csetch, unich) not in self.pass_enctest:
326-
self.assertEqual(unich.encode(self.encoding), csetch)
326+
try:
327+
self.assertEqual(unich.encode(self.encoding), csetch)
328+
except UnicodeError, exc:
329+
self.fail('Encoding failed while testing %s -> %s: %s' % (
330+
repr(unich), repr(csetch), exc.reason))
327331
if (csetch, unich) not in self.pass_dectest:
328-
self.assertEqual(unicode(csetch, self.encoding), unich)
332+
try:
333+
self.assertEqual(csetch.decode(self.encoding), unich)
334+
except UnicodeError, exc:
335+
self.fail('Decoding failed while testing %s -> %s: %s' % (
336+
repr(csetch), repr(unich), exc.reason))
329337

330338
def load_teststring(encoding):
331339
from test import cjkencodings_test

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,8 @@ Library
11181118
Extension Modules
11191119
-----------------
11201120

1121+
- Updated ``big5hkscs`` codec to the HKSCS revision of 2004.
1122+
11211123
- #1940: make it possible to use curses.filter() before curses.initscr()
11221124
as the documentation says.
11231125

Modules/cjkcodecs/_codecs_hk.c

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@ CODEC_INIT(big5hkscs)
2626
return 0;
2727
}
2828

29+
/*
30+
* There are four possible pair unicode -> big5hkscs maps as in HKSCS 2004:
31+
* U+00CA U+0304 -> 8862 (U+00CA alone is mapped to 8866)
32+
* U+00CA U+030C -> 8864
33+
* U+00EA U+0304 -> 88a3 (U+00EA alone is mapped to 88a7)
34+
* U+00EA U+030C -> 88a5
35+
* These are handled by not mapping tables but a hand-written code.
36+
*/
37+
static const DBCHAR big5hkscs_pairenc_table[4] = {0x8862, 0x8864, 0x88a3, 0x88a5};
38+
2939
ENCODER(big5hkscs)
3040
{
3141
while (inleft > 0) {
@@ -46,7 +56,27 @@ ENCODER(big5hkscs)
4656
REQUIRE_OUTBUF(2)
4757

4858
if (c < 0x10000) {
49-
TRYMAP_ENC(big5hkscs_bmp, code, c);
59+
TRYMAP_ENC(big5hkscs_bmp, code, c) {
60+
if (code == MULTIC) {
61+
if (inleft >= 2 &&
62+
((c & 0xffdf) == 0x00ca) &&
63+
(((*inbuf)[1] & 0xfff7) == 0x0304)) {
64+
code = big5hkscs_pairenc_table[
65+
((c >> 4) |
66+
((*inbuf)[1] >> 3)) & 3];
67+
insize = 2;
68+
}
69+
else if (inleft < 2 &&
70+
!(flags & MBENC_FLUSH))
71+
return MBERR_TOOFEW;
72+
else {
73+
if (c == 0xca)
74+
code = 0x8866;
75+
else /* c == 0xea */
76+
code = 0x88a7;
77+
}
78+
}
79+
}
5080
else TRYMAP_ENC(big5, code, c);
5181
else return 1;
5282
}
@@ -67,7 +97,7 @@ ENCODER(big5hkscs)
6797
return 0;
6898
}
6999

70-
#define BH2S(c1, c2) (((c1) - 0x88) * (0xfe - 0x40 + 1) + ((c2) - 0x40))
100+
#define BH2S(c1, c2) (((c1) - 0x87) * (0xfe - 0x40 + 1) + ((c2) - 0x40))
71101

72102
DECODER(big5hkscs)
73103
{
@@ -96,19 +126,19 @@ hkscsdec: TRYMAP_DEC(big5hkscs, decoded, c, IN2) {
96126
int s = BH2S(c, IN2);
97127
const unsigned char *hintbase;
98128

99-
assert(0x88 <= c && c <= 0xfe);
129+
assert(0x87 <= c && c <= 0xfe);
100130
assert(0x40 <= IN2 && IN2 <= 0xfe);
101131

102-
if (BH2S(0x88, 0x40) <= s && s <= BH2S(0xa0, 0xfe)) {
132+
if (BH2S(0x87, 0x40) <= s && s <= BH2S(0xa0, 0xfe)) {
103133
hintbase = big5hkscs_phint_0;
104-
s -= BH2S(0x88, 0x40);
134+
s -= BH2S(0x87, 0x40);
105135
}
106136
else if (BH2S(0xc6,0xa1) <= s && s <= BH2S(0xc8,0xfe)){
107-
hintbase = big5hkscs_phint_11939;
137+
hintbase = big5hkscs_phint_12130;
108138
s -= BH2S(0xc6, 0xa1);
109139
}
110140
else if (BH2S(0xf9,0xd6) <= s && s <= BH2S(0xfe,0xfe)){
111-
hintbase = big5hkscs_phint_21733;
141+
hintbase = big5hkscs_phint_21924;
112142
s -= BH2S(0xf9, 0xd6);
113143
}
114144
else
@@ -123,7 +153,17 @@ hkscsdec: TRYMAP_DEC(big5hkscs, decoded, c, IN2) {
123153
NEXT(2, 1)
124154
}
125155
}
126-
else return 2;
156+
else {
157+
switch ((c << 8) | IN2) {
158+
case 0x8862: WRITE2(0x00ca, 0x0304); break;
159+
case 0x8864: WRITE2(0x00ca, 0x030c); break;
160+
case 0x88a3: WRITE2(0x00ea, 0x0304); break;
161+
case 0x88a5: WRITE2(0x00ea, 0x030c); break;
162+
default: return 2;
163+
}
164+
165+
NEXT(2, 2) /* all decoded codepoints are pairs, above. */
166+
}
127167
}
128168

129169
return 0;

0 commit comments

Comments
 (0)