• R/O
  • HTTP
  • SSH
  • HTTPS

hengband: Commit

変愚蛮怒のメインリポジトリです


Commit MetaInfo

Revision5b056aad4cc5688068d021d7b60561ee8190f0c8 (tree)
Time2014-02-28 21:30:26
AuthorHabu <habu@user...>
CommiterHabu

Log Message

ファイルの読み込み時に文字コードを適切なものに変換するように修正

ファイルを読み込み時に文字コードがUTF-8かどうかを推測し、UTF-8ならば
システムの文字コード(WindowsならCP932、Linux/UNIXならEUC-JP)に
変換して読み込むようにした。

Change Summary

Incremental Difference

--- a/src/externs.h
+++ b/src/externs.h
@@ -1763,6 +1763,7 @@ extern void sjis2euc(char *str);
17631763 extern void euc2sjis(char *str);
17641764 extern byte codeconv(char *str);
17651765 extern bool iskanji2(cptr s, int x);
1766+extern void guess_convert_to_system_encoding(char* strbuf, int buflen);
17661767 #endif
17671768
17681769 #ifdef WORLD_SCORE
--- a/src/japanese.c
+++ b/src/japanese.c
@@ -357,5 +357,92 @@ bool iskanji2(cptr s, int x)
357357 return FALSE;
358358 }
359359
360-#endif /* JP */
360+/*!
361+ * @brief 文字列の文字コードがASCIIかどうかを判定する
362+ * @param str 判定する文字列へのポインタ
363+ * @return 文字列の文字コードがASCIIならTRUE、そうでなければFALSE
364+ */
365+static bool is_ascii_str(cptr str)
366+{
367+ for (;*str; str++) {
368+ if (!(0x00 < *str && *str <= 0x7f))
369+ return FALSE;
370+ }
371+ return TRUE;
372+}
373+
374+/*!
375+ * @brief 文字列の文字コードがUTF-8かどうかを判定する
376+ * @param str 判定する文字列へのポインタ
377+ * @return 文字列の文字コードがASCIIならTRUE、そうでなければFALSE
378+ */
379+static bool is_utf8_str(cptr str)
380+{
381+ const unsigned char* p;
382+ for (p = (const unsigned char*)str; *p; p++) {
383+ int subseq_num = 0;
384+ if (0x00 < *p && *p <= 0x7f) continue;
385+
386+ if ((*p & 0xe0) == 0xc0) subseq_num = 1;
387+ if ((*p & 0xf0) == 0xe0) subseq_num = 2;
388+ if ((*p & 0xf8) == 0xf0) subseq_num = 3;
389+
390+ if (subseq_num == 0) return FALSE;
391+ while (subseq_num--) {
392+ p++;
393+ if (!*p || (*p & 0xc0) != 0x80) return FALSE;
394+ }
395+ }
396+ return TRUE;
397+}
398+
399+/*!
400+ * @brief 文字コードがUTF-8の文字列をシステムの文字コードに変換する
401+ * @param utf8_str 変換するUTF-8の文字列へのポインタ
402+ * @param sys_str_buffer 変換したシステムの文字コードの文字列を格納するバッファへのポインタ
403+ * @param sys_str_buflen 変換したシステムの文字コードの文字列を格納するバッファの長さ
404+ * @return なし
405+ */
406+#ifdef SJIS
407+#ifdef WINDOWS
408+#include <Windows.h>
409+static void utf8_to_sys(cptr utf8_str, char* sys_str_buffer, size_t sys_str_buflen)
410+{
411+ LPWSTR utf16buf;
412+ int input_str_len = strlen(utf8_str);
413+ int len;
414+
415+ C_MAKE(utf16buf, input_str_len, WCHAR);
416+
417+ MultiByteToWideChar( CP_UTF8, 0, (LPCSTR)utf8_str, input_str_len, (LPWSTR)utf16buf, input_str_len);
418+
419+ len = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)utf16buf, -1, (LPSTR)sys_str_buffer, sys_str_buflen, NULL, NULL );
420+
421+ sys_str_buffer[len] = '\0';
422+
423+ C_KILL(utf16buf, input_str_len, WCHAR);
424+}
425+#endif
426+#endif
361427
428+/*!
429+ * @brief 受け取った文字列の文字コードを推定し、システムの文字コードへ変換する
430+ * @param strbuf 変換する文字列を格納したバッファへのポインタ。
431+ * バッファは変換した文字列で上書きされる。
432+ * @param buflen バッファの長さ。
433+ * @return なし
434+ */
435+void guess_convert_to_system_encoding(char* strbuf, int buflen)
436+{
437+ if (is_ascii_str(strbuf)) return;
438+
439+ if (is_utf8_str(strbuf)) {
440+ char* work;
441+ C_MAKE(work, buflen, char);
442+ strncpy(work, strbuf, buflen);
443+ utf8_to_sys(work, strbuf, buflen);
444+ C_KILL(work, buflen, char);
445+ }
446+}
447+
448+#endif /* JP */
--- a/src/util.c
+++ b/src/util.c
@@ -452,6 +452,7 @@ errr my_fgets(FILE *fff, char *buf, huge n)
452452 /* Read a line */
453453 if (fgets(tmp, 1024, fff))
454454 {
455+ guess_convert_to_system_encoding(tmp, sizeof(tmp));
455456 /* Convert weirdness */
456457 for (s = tmp; *s; s++)
457458 {
Show on old repository browser