• R/O
  • HTTP
  • SSH
  • HTTPS

提交

标签
No Tags

Frequently used words (click to add to your profile)

javaandroidc++linuxc#objective-ccocoa誰得qtrubypythongamewindowsbathyscaphephpguic翻訳omegattwitterframeworktestbtronarduinovb.net計画中(planning stage)directxpreviewerゲームエンジンdom

Tera Termの個人的な作業用リポジトリ


Commit MetaInfo

修订版de91f85dedd79a353c409f61aefba4a7e36404f7 (tree)
时间2018-05-29 20:45:59
作者IWAMOTO Kouichi <sue@iwmt...>
CommiterIWAMOTO Kouichi

Log Message

UTF-8 のパース処理を書き直した。

4byte(以上)の文字が来た時に、表示できないだけではなく、後続の文字の
パース処理にまで影響が出て文字化けしていた。
4byte(以上)の文字が表示できないにしても、後続の文字が文字化けしない
ように、パース処理だけでも4byte(以上)を扱えるようにした。

更改概述

差异

--- a/teraterm/teraterm/vtterm.c
+++ b/teraterm/teraterm/vtterm.c
@@ -5432,135 +5432,102 @@ BOOL ParseFirstUTF8(BYTE b, int proc_combining)
54325432 // returns TRUE if b is processed
54335433 // (actually allways returns TRUE)
54345434 {
5435- static BYTE buf[3];
5436- static int count = 0;
5437- static int can_combining = 0;
5438- static unsigned int first_code;
5439- static int first_code_index;
5440-
5441- unsigned int code;
5442- unsigned short cset;
5443- char *locptr;
5444-
5445- locptr = setlocale(LC_ALL, ts.Locale);
5446-
5447- if (ts.FallbackToCP932 && Fallbacked) {
5448- return ParseFirstJP(b);
5449- }
5435+ static BYTE buf[6];
5436+ static int buf_len = 0;
5437+ static int enc_len = 0;
5438+ static unsigned int code = 0, prev_code = 0, can_combining = 0;
5439+ static int prev_index = 0;
5440+ unsigned short cset = 0;
5441+ int i;
54505442
5451- if ((b & 0x80) != 0x80 || ((b & 0xe0) == 0x80 && count == 0)) {
5452- // 1バイト目および2バイト目がASCIIの場合は、すべてASCII出力とする。
5453- // 1バイト目がC1制御文字(0x80-0x9f)の場合も同様。
5454- if (count == 0 || count == 1) {
5455- if (proc_combining == 1 && can_combining == 1) {
5456- UnicodeToCP932(first_code);
5443+ if (enc_len == 0) {
5444+ if (b < 0xC0 || b >= 0xFE) {
5445+ if (can_combining) {
5446+ UnicodeToCP932(prev_code);
54575447 can_combining = 0;
54585448 }
5459-
5460- if (count == 1) {
5461- ParseASCII(buf[0]);
5462- }
54635449 ParseASCII(b);
5464-
5465- count = 0; // reset counter
54665450 return TRUE;
54675451 }
5468- }
5469-
5470- buf[count++] = b;
5471- if (count < 2) {
5452+ else if (b < 0xE0) { // 2 byte sequence
5453+ enc_len = 2;
5454+ code = b & 0x1f;
5455+ }
5456+ else if (b < 0xF0) { // 3 byte sequence
5457+ enc_len = 3;
5458+ code = b & 0x0f;
5459+ }
5460+ else if (b < 0xF8) { // 4 byte sequence
5461+ enc_len = 4;
5462+ code = b & 0x07;
5463+ }
5464+ else if (b < 0xFC) { // 5 byte sequence -- invalid
5465+ enc_len = 5;
5466+ code = b & 0x03;
5467+ }
5468+ else if (b < 0xFE) { // 6 byte sequence -- invalid
5469+ enc_len = 6;
5470+ code = b & 0x01;
5471+ }
5472+ buf[0] = b;
5473+ buf_len = 1;
54725474 return TRUE;
54735475 }
5474-
5475- // 2バイトコードの場合
5476- if ((buf[0] & 0xe0) == 0xc0) {
5477- if ((buf[1] & 0xc0) == 0x80) {
5478-
5479- if (proc_combining == 1 && can_combining == 1) {
5480- UnicodeToCP932(first_code);
5481- can_combining = 0;
5482- }
5483-
5484- code = ((buf[0] & 0x1f) << 6);
5485- code |= ((buf[1] & 0x3f));
5486-
5487- UnicodeToCP932(code);
5476+ else {
5477+ if ((b & 0xC0) == 0x80) {
5478+ buf[buf_len++] = b;
54885479 }
54895480 else {
5490- ParseASCII(buf[0]);
5491- ParseASCII(buf[1]);
5481+ if (can_combining) {
5482+ UnicodeToCP932(prev_code);
5483+ can_combining = 0;
5484+ }
5485+ for (i=0; i<buf_len; i++) {
5486+ ParseASCII(buf[i]);
5487+ }
5488+ enc_len = 0;
5489+ buf_len = 0;
5490+ return ParseFirstUTF8(b, proc_combining);
54925491 }
5493- count = 0;
5494- return TRUE;
54955492 }
54965493
5497- if (count < 3) {
5498- return TRUE;
5499- }
5500-
5501- if ((buf[0] & 0xe0) == 0xe0 &&
5502- (buf[1] & 0xc0) == 0x80 &&
5503- (buf[2] & 0xc0) == 0x80) { // 3バイトコードの場合
5504-
5505- // UTF-8 BOM(Byte Order Mark)
5506- if (buf[0] == 0xef && buf[1] == 0xbb && buf[2] == 0xbf) {
5507- goto skip;
5494+ if (enc_len == buf_len) {
5495+ for (i=1; i<enc_len; i++) {
5496+ code = (code << 6) | (buf[i] & 0x3f);
55085497 }
5498+ enc_len = 0;
5499+ buf_len = 0;
55095500
5510- code = ((buf[0] & 0xf) << 12);
5511- code |= ((buf[1] & 0x3f) << 6);
5512- code |= ((buf[2] & 0x3f));
5501+ if (code == 0xfeff) { // BOM
5502+ return TRUE;
5503+ }
55135504
5514- if (proc_combining == 1) {
5515- if (can_combining == 0) {
5516- if ((first_code_index = GetIndexOfCombiningFirstCode(
5517- code, mapCombiningToPrecomposed, MAPSIZE(mapCombiningToPrecomposed)
5518- )) != -1) {
5519- can_combining = 1;
5520- first_code = code;
5521- count = 0;
5522- return (TRUE);
5523- }
5524- } else {
5505+ if (proc_combining) {
5506+ if (can_combining) {
55255507 can_combining = 0;
5526- cset = GetPrecomposedChar(first_code_index, first_code, code, mapCombiningToPrecomposed, MAPSIZE(mapCombiningToPrecomposed));
5527- if (cset != 0) { // success
5528- code = cset;
5529-
5530- } else { // error
5531- // 2つめの文字が半濁点の1文字目に相当する場合は、再度検索を続ける。(2005.10.15 yutaka)
5532- if ((first_code_index = GetIndexOfCombiningFirstCode(
5533- code, mapCombiningToPrecomposed, MAPSIZE(mapCombiningToPrecomposed)
5534- )) != -1) {
5535-
5536- // 1つめの文字はそのまま出力する
5537- UnicodeToCP932(first_code);
5538-
5539- can_combining = 1;
5540- first_code = code;
5541- count = 0;
5542- return (TRUE);
5543- }
5508+ cset = GetPrecomposedChar(prev_index, prev_code, code, mapCombiningToPrecomposed, MAPSIZE(mapCombiningToPrecomposed));
5509+ prev_index = 0;
55445510
5545- UnicodeToCP932(first_code);
5546- UnicodeToCP932(code);
5547- count = 0;
5548- return (TRUE);
5511+ if (cset) {
5512+ UnicodeToCP932(cset);
5513+ prev_code = 0;
5514+ return TRUE;
55495515 }
5516+ else {
5517+ UnicodeToCP932(prev_code);
5518+ prev_code = 0;
5519+ }
5520+ }
5521+
5522+ prev_index = GetIndexOfCombiningFirstCode(code, mapCombiningToPrecomposed, MAPSIZE(mapCombiningToPrecomposed));
5523+ if (prev_index != -1) {
5524+ can_combining = 1;
5525+ prev_code = code;
5526+ return TRUE;
55505527 }
55515528 }
55525529
55535530 UnicodeToCP932(code);
5554-
5555-skip:
5556- count = 0;
5557-
5558- } else {
5559- ParseASCII(buf[0]);
5560- ParseASCII(buf[1]);
5561- ParseASCII(buf[2]);
5562- count = 0;
5563-
55645531 }
55655532
55665533 return TRUE;