1 /* File: japanese.c */
8 typedef struct convert_key convert_key;
16 static const convert_key s2j_table[] = {
17 {"mb","nb"}, {"mp","np"}, {"mv","nv"}, {"mm","nm"},
19 /* sindar:シンダール parantir:パランティア feanor:フェアノール */
20 {"ar$","a-ru$"}, {"ir$","ia$"}, {"or$","o-ru$"},
21 {"ra","ラ"}, {"ri","リ"}, {"ru","ル"}, {"re","レ"}, {"ro","ロ"},
22 {"ir","ia"}, {"ur","ua"}, {"er","ea"}, {"ar","aル"},
23 {"sha","シャ"}, {"shi","シ"}, {"shu","シュ"}, {"she","シェ"}, {"sho","ショ"},
24 {"tha","サ"}, {"thi","シ"}, {"thu","ス"}, {"the","セ"}, {"tho","ソ"},
25 {"cha","ハ"}, {"chi","ヒ"}, {"chu","フ"}, {"che","ヘ"}, {"cho","ホ"},
26 {"dha","ザ"}, {"dhi","ジ"}, {"dhu","ズ"}, {"dhe","ゼ"}, {"dho","ゾ"},
27 {"ba","バ"}, {"bi","ビ"}, {"bu","ブ"}, {"be","ベ"}, {"bo","ボ"},
28 {"ca","カ"}, {"ci","キ"}, {"cu","ク"}, {"ce","ケ"}, {"co","コ"},
29 {"da","ダ"}, {"di","ディ"}, {"du","ドゥ"}, {"de","デ"}, {"do","ド"},
30 {"fa","ファ"}, {"fi","フィ"}, {"fu","フ"}, {"fe","フェ"}, {"fo","フォ"},
31 {"ga","ガ"}, {"gi","ギ"}, {"gu","グ"}, {"ge","ゲ"}, {"go","ゴ"},
32 {"ha","ハ"}, {"hi","ヒ"}, {"hu","フ"}, {"he","ヘ"}, {"ho","ホ"},
33 {"ja","ジャ"}, {"ji","ジ"}, {"ju","ジュ"}, {"je","ジェ"}, {"jo","ジョ"},
34 {"ka","カ"}, {"ki","キ"}, {"ku","ク"}, {"ke","ケ"}, {"ko","コ"},
35 {"la","ラ"}, {"li","リ"}, {"lu","ル"}, {"le","レ"}, {"lo","ロ"},
36 {"ma","マ"}, {"mi","ミ"}, {"mu","ム"}, {"me","メ"}, {"mo","モ"},
37 {"na","ナ"}, {"ni","ニ"}, {"nu","ヌ"}, {"ne","ネ"}, {"no","ノ"},
38 {"pa","パ"}, {"pi","ピ"}, {"pu","プ"}, {"pe","ペ"}, {"po","ポ"},
40 {"sa","サ"}, {"si","シ"}, {"su","ス"}, {"se","セ"}, {"so","ソ"},
41 {"ta","タ"}, {"ti","ティ"}, {"tu","トゥ"}, {"te","テ"}, {"to","ト"},
42 {"va","ヴァ"}, {"vi","ヴィ"}, {"vu","ヴ"}, {"ve","ヴェ"}, {"vo","ヴォ"},
43 {"wa","ワ"}, {"wi","ウィ"}, {"wu","ウ"}, {"we","ウェ"}, {"wo","ウォ"},
44 {"ya","ヤ"}, {"yu","ユ"}, {"yo","ヨ"},
45 {"za","ザ"}, {"zi","ジ"}, {"zu","ズ"}, {"ze","ゼ"}, {"zo","ゾ"},
46 {"dh","ズ"}, {"ch","フ"}, {"th","ス"},
47 {"b","ブ"}, {"c","ク"}, {"d","ド"}, {"f","フ"}, {"g","グ"},
48 {"h","フ"}, {"j","ジュ"}, {"k","ク"}, {"l","ル"}, {"m","ム"},
49 {"n","ン"}, {"p","プ"}, {"q","ク"}, {"r","ル"}, {"s","ス"},
50 {"t","ト"}, {"v","ヴ"}, {"w","ウ"}, {"y","イ"},
51 {"a","ア"}, {"i","イ"}, {"u","ウ"}, {"e","エ"}, {"o","オ"},
56 /* シンダリンを日本語の読みに変換する */
57 void sindarin_to_kana(char *kana, const char *sindarin)
62 sprintf(kana, "%s$", sindarin);
63 for (idx = 0; kana[idx]; idx++)
64 if (isupper(kana[idx])) kana[idx] = tolower(kana[idx]);
66 for (idx = 0; s2j_table[idx].key1 != NULL; idx++)
68 cptr pat1 = s2j_table[idx].key1;
69 cptr pat2 = s2j_table[idx].key2;
70 int len = strlen(pat1);
76 if (strncmp(src, pat1, len) == 0)
102 while (kana[idx] != '$') idx++;
108 /*日本語動詞活用 (打つ>打って,打ち etc) */
109 /* JVERB_AND: 殴る,蹴る > 殴り,蹴る */
110 /* JVERB_TO: 殴る,蹴る > 殴って蹴る */
111 /* JVERB_OR: 殴る,蹴る > 殴ったり蹴ったり */
113 static const struct jverb_table_t {
117 { "する", {"し", "して", "した"}},
118 { "いる", {"いて", "いて", "いた"}},
120 { "える", {"え", "えて", "えた"}},
121 { "ける", {"け", "けて", "けた"}},
122 { "げる", {"げ", "えて", "げた"}},
123 { "せる", {"せ", "せて", "せた"}},
124 { "ぜる", {"ぜ", "ぜて", "ぜた"}},
125 { "てる", {"て", "てって", "てった"}},
126 { "でる", {"で", "でて", "でた"}},
127 { "ねる", {"ね", "ねて", "ねた"}},
128 { "へる", {"へ", "へて", "へた"}},
129 { "べる", {"べ", "べて", "べた"}},
130 { "める", {"め", "めて", "めた"}},
131 { "れる", {"れ", "れて", "れた"}},
133 { "う", {"い", "って", "った"}},
134 { "く", {"き", "いて", "いた"}},
135 { "ぐ", {"ぎ", "いで", "いだ"}},
136 { "す", {"し", "して", "した"}},
137 { "ず", {"じ", "じて", "じた"}},
138 { "つ", {"ち", "って", "った"}},
139 { "づ", {"ぢ", "って", "った"}},
140 { "ぬ", {"に", "ねて", "ねた"}},
141 { "ふ", {"ひ", "へて", "へた"}},
142 { "ぶ", {"び", "んで", "んだ"}},
143 { "む", {"み", "んで", "んだ"}},
144 { "る", {"り", "って", "った"}},
145 { NULL, {"そして", "ことにより", "ことや"}},
148 void jverb(const char *in , char *out , int flag)
150 const struct jverb_table_t * p;
151 int in_len = strlen(in);
155 for (p = jverb_table; p->from; p++) {
156 int from_len = strlen(p->from);
157 if (strncmp(&in[in_len-from_len], p->from, from_len) == 0) {
158 strcpy(&out[in_len - from_len], p->to[flag - 1]);
164 strcpy(&out[in_len], p->to[flag - 1]);
169 * Convert SJIS string to EUC string
171 void sjis2euc(char *str)
174 unsigned char c1, c2;
177 int len = strlen(str);
179 C_MAKE(tmp, len+1, byte);
181 for (i = 0; i < len; i++)
190 c1 = c1 * 2 - (c1 >= 0xe0 ? 0xe0 : 0x60);
195 c1 = c1 * 2 - (c1 >= 0xe0 ? 0xe1 : 0x61);
196 c2 += 0x60 + (c2 < 0x7f);
205 strcpy(str, (char *)tmp);
207 C_KILL(tmp, len+1, byte);
212 * Convert EUC string to SJIS string
214 void euc2sjis(char *str)
217 unsigned char c1, c2;
220 int len = strlen(str);
222 C_MAKE(tmp, len+1, byte);
224 for (i = 0; i < len; i++)
233 c1 = (c1 >> 1) + (c1 < 0xdf ? 0x31 : 0x71);
234 c2 -= 0x60 + (c2 < 0xe0);
238 c1 = (c1 >> 1) + (c1 < 0xdf ? 0x30 : 0x70);
249 strcpy(str, (char *)tmp);
251 C_KILL(tmp, len+1, byte);
256 * strを環境に合った文字コードに変換し、変換前の文字コードを返す。
260 * 1: ASCII (Never known to be ASCII in this function.)
264 byte codeconv(char *str)
269 for (i = 0; str[i]; i++)
278 if (!(c1 & 0x80)) continue;
284 if (((0xa1 <= c1 && c1 <= 0xdf) || (0xfd <= c1 && c1 <= 0xfe)) &&
285 (0xa1 <= c2 && c2 <= 0xfe))
287 /* Only EUC is allowed */
302 else if (((0x81 <= c1 && c1 <= 0x9f) &&
303 ((0x40 <= c2 && c2 <= 0x7e) || (0x80 <= c2 && c2 <= 0xfc))) ||
304 ((0xe0 <= c1 && c1 <= 0xfc) &&
305 (0x40 <= c2 && c2 <= 0x7e)))
307 /* Only SJIS is allowed */
342 /* Return kanji code */
346 /* 文字列sのxバイト目が漢字の1バイト目かどうか判定する */
347 bool iskanji2(cptr s, int x)
351 for (i = 0; i < x; i++)
353 if (iskanji(s[i])) i++;
355 if ((x == i) && iskanji(s[x])) return TRUE;
361 * @brief 文字列の文字コードがASCIIかどうかを判定する
362 * @param str 判定する文字列へのポインタ
363 * @return 文字列の文字コードがASCIIならTRUE、そうでなければFALSE
365 static bool is_ascii_str(cptr str)
368 if (!(0x00 < *str && *str <= 0x7f))
375 * @brief 文字列の文字コードがUTF-8かどうかを判定する
376 * @param str 判定する文字列へのポインタ
377 * @return 文字列の文字コードがUTF-8ならTRUE、そうでなければFALSE
379 static bool is_utf8_str(cptr str)
381 const unsigned char* p;
382 for (p = (const unsigned char*)str; *p; p++) {
384 if (0x00 < *p && *p <= 0x7f) continue;
386 if ((*p & 0xe0) == 0xc0) subseq_num = 1;
387 if ((*p & 0xf0) == 0xe0) subseq_num = 2;
388 if ((*p & 0xf8) == 0xf0) subseq_num = 3;
390 if (subseq_num == 0) return FALSE;
391 while (subseq_num--) {
393 if (!*p || (*p & 0xc0) != 0x80) return FALSE;
401 #elif defined(SJIS) && defined(WINDOWS)
405 * @brief 文字コードがUTF-8の文字列をシステムの文字コードに変換する
406 * @param utf8_str 変換するUTF-8の文字列へのポインタ
407 * @param sys_str_buffer 変換したシステムの文字コードの文字列を格納するバッファへのポインタ
408 * @param sys_str_buflen 変換したシステムの文字コードの文字列を格納するバッファの長さ
409 * @return 変換に成功した場合TRUE、失敗した場合FALSEを返す
411 static bool utf8_to_sys(char* utf8_str, char* sys_str_buffer, size_t sys_str_buflen)
415 iconv_t cd = iconv_open("EUC-JP-MS", "UTF-8");
416 size_t utf8_len = strlen(utf8_str) + 1; /* include termination character */
417 char *from = utf8_str;
418 int ret = iconv(cd, &from, &utf8_len, &sys_str_buffer, &sys_str_buflen);
422 #elif defined(SJIS) && defined(WINDOWS)
425 int input_len = strlen(utf8_str) + 1; /* include termination character */
427 C_MAKE(utf16buf, input_len, WCHAR);
429 /* UTF-8 -> UTF-16 */
430 if (MultiByteToWideChar( CP_UTF8, 0, utf8_str, input_len, utf16buf, input_len) == 0) {
431 C_KILL(utf16buf, input_len, WCHAR);
435 /* UTF-8 -> SJIS(CP932) */
436 if (WideCharToMultiByte( CP_ACP, 0, utf16buf, -1, sys_str_buffer, sys_str_buflen, NULL, NULL ) == 0) {
437 C_KILL(utf16buf, input_len, WCHAR);
441 C_KILL(utf16buf, input_len, WCHAR);
448 * @brief 受け取った文字列の文字コードを推定し、システムの文字コードへ変換する
449 * @param strbuf 変換する文字列を格納したバッファへのポインタ。
450 * バッファは変換した文字列で上書きされる。
451 * UTF-8からSJISもしくはEUCへの変換を想定しているのでバッファの長さが足りなくなることはない。
452 * @param buflen バッファの長さ。
455 void guess_convert_to_system_encoding(char* strbuf, int buflen)
457 if (is_ascii_str(strbuf)) return;
459 if (is_utf8_str(strbuf)) {
461 C_MAKE(work, buflen, char);
462 my_strcpy(work, strbuf, buflen);
463 if (!utf8_to_sys(work, strbuf, buflen)) {
464 msg_print("警告:文字コードの変換に失敗しました");
467 C_KILL(work, buflen, char);