« ネポス・ナポス | トップページ | プレイヤンミクロ »
2005.09.07
doxygen 日本語文字化け対策 その3
「doxygen 日本語文字化け対策 その2」で示した文字化けを解決することができました。ドキュメント生成対象ファイルを読み込むときに、「2バイト目が 0x5c になる文字」の直後に 0x5c を挿入してやれば OK。
doctokenizer.cpp (doctokenizer.l) をいじる必要はなく、「doxygen 日本語文字化け対策」でいじった commentscan.cpp をさらにいじることで対処可能です。ファイルからバッファに文字列を読み込む処理
- yyread(char *buf,int max_size)
を修正することになります。
以下、オリジナルの(doxygen 日本語文字化け対策」の修正を施す前の) commentscan.cpp に対して前回と今回の修正(パッチ)を一気に当てるための context diff を示します。
*** commentscan.cpp.orig Thu Jul 21 00:00:30 2005 --- commentscan.cpp Wed Sep 07 19:59:29 2005 *************** *** 3412,3421 **** --- 3412,3450 ---- static int yyread(char *buf,int max_size) { + #if defined(_WIN32) + static bool isJapanese = theTranslator->idLanguage()=="japanese" || + theTranslator->idLanguage()=="japanese-en"; + static bool isKanji = false; + + #ifndef iskanji1 + #define iskanji1(s) ((((unsigned char)(s)>=0x81) && ((unsigned char)(s)<=0x9f)) || \ + (((unsigned char)(s)>=0xe0) && ((unsigned char)(s)<=0xfc)) ) + #endif + + if ( inputPosition == 0 ) + isKanji = false; + #endif /* _WIN32 */ + prevPosition=inputPosition; int c=0; while( c < max_size && inputString[inputPosition] ) { + #if defined(_WIN32) + if ( isJapanese ) { + if ( !isKanji && iskanji1(inputString[inputPosition]) ) + isKanji = true; + else if ( isKanji ) { + isKanji = false; + if ( inputString[inputPosition] == '\\' ) { + // 漢字の2バイト目が 0x5c のとき特別扱いが必要 + *buf++ = '\\'; + c++; + } + } + } + #endif /* _WIN32 */ + *buf = inputString[inputPosition++] ; //printf("%d (%c)\n",*buf,*buf); c++; buf++; *************** *** 3649,3654 **** --- 3678,3689 ---- register yy_state_type yy_current_state; register char *yy_cp = NULL, *yy_bp = NULL; register int yy_act; + #if defined(_WIN32) + static bool isJapanese = theTranslator->idLanguage()=="japanese" || + theTranslator->idLanguage()=="japanese-en"; + bool isKanji = false; + bool kanji5C = false; + #endif /* _WIN32 */ #line 779 "commentscan.l" *************** *** 3715,3720 **** --- 3750,3770 ---- do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + + #if defined(_WIN32) + if ( isJapanese ) { + if ( !isKanji && iskanji1(*yy_cp) ) + isKanji = true; + else if ( isKanji ) { + isKanji = false; + if ( *yy_cp == '\\' ) + kanji5C = true; // 漢字の2バイト目が 0x5c のとき特別扱いが必要 + } + } + if ( kanji5C ) + kanji5C = false; + else { + #endif /* _WIN32 */ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; *************** *** 3722,3727 **** --- 3772,3780 ---- yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + #if defined(_WIN32) + } + #endif /* _WIN32 */ *yy_state_ptr++ = yy_current_state; ++yy_cp; }
これで(今までに発見したパターンの)文字化けは完全になくなるはずです。まだ未知の文字化けパターンがあるかもしれませんが、見つけたときに対処することにします。
関連記事
- doxygen 日本語文字化け対策
- doxygen + graphviz で日本語を使った絵をドキュメントに埋め込む
- doxygen 日本語文字化け対策 その2
- doxygen (はてなダイアリーキーワード)
- Doxygen を使おう (OKA Toshiyuki さん)
- doxygen用コメントの書き方 (サクラエディタ一次配布サイト)
投稿者: tsupo 2005.09.07 午後 08:48
| 固定リンク
|
|
|
|
|
アマゾンわくわく探検隊
トラックバック
この記事のトラックバックURL:
この記事へのトラックバック一覧です: doxygen 日本語文字化け対策 その3:
コメント
ずいぶん古い記事にコメントをつけてしまって申し訳ありません。
実は最新のdoxygen1.4.6に日本語対応の部分を入れようとしているのですが、
doxygenのHPから落として来たソースファイルをVC6でビルドすると英語オンリーになって
しまいます。英語オンリーをはずすとビルドが通りません。
(これはヘッダーにある文字列がEUCで書かれている所為だという事はわかりました)
もしかしてMinGWの環境を構築してビルドしないと駄目なんでしょうか?
できれば、 graphvizの対応まで入れたものを作成したいと考えています。
というか、本家に取り込んでもらえないものなんですかねぇ。
投稿者: PATIO (2006.06.08 午後 09:50)
MinGW というか、cygwin 環境で gcc を使ってビルドする分には EUC-JP のままビルドしちゃった方がいいかもしれません。ただし、graphviz まで対応しようとすると、どこかに UTF-8 変換処理を組み込む必要があります。
一方、VC++ 6 でビルドする場合、lex + yacc(もしくは bison)で .l や .y ファイルを元に .c ファイルを生成する必要があります。
私のパッチは、この yacc(bison) の出力する .c に対してあてるパッチなので、本家に取り込んでもらうのは難しいと思っています。本家が UTF-8 対応になるのがいちばんいいのですが、そうなると yacc(bison) を使わずに手作りでコード解析処理を作る必要があるので、doxygen をもう一度最初からスクラッチ・アンド・ビルドするのとほぼ同じ作業を行なうことになります。この辺が UTF-8 対応を遅らせている原因だと思われます。マルチバイト文字に対応したコンパイラコンパイラがあれば、いちばんいいんですけど。
暇を見つけて、そのうち doxygen 1.4.6 用のパッチが作れるか、見てみたいと思います。期待せずにお待ちください。
投稿者: tsupo (2006.06.08 午後 11:58)
お返事ありがとうございます。
cygwin環境で作ったバイナリはcygwin上でしか動かないと思ってましたが、違うのかな。
以前にcygwin環境を一時的に作った事があったんですが、また作って試してみます。
MinGWと書いていたのは、これだと作成したバイナリがWindows上でそのまま動くだろうと思ったからなんです。
この辺の知識を一度整理しないといけないなぁ。
今ちょっと時間が取れそうに無いので時間を見てまたチャレンジしてみます。
投稿者: PATIO (2006.06.09 午前 10:18)
その後、試してみた所、MinGWでビルドが何とかできるようになり、
コメント部分の文字化けに関しては何とかなるようになりました。
graphviz対策を採る為、libiconv-1.9.2をMinGWにPORTして使えるように
したのですが、どうしてもgraphvizの文字化けが解消できない状態です。
iconvに引き渡すCP932をSHIFT_JISに変更したり、フォントをmsgothic.ttcに変更してみたりしましたが、文字化けは一向に変わりませんでした。
多分、どこかのやり方が不味いのだろうと思うのですが、
今のところ、どの変が不味いのかわからない状況です。
コード的には、「doxygen + graphviz で日本語を使った絵をドキュメントに埋め込む」の内容を最新版の内容を見て入れて見ています。
投稿者: PATIO (2006.06.14 午後 04:58)
その後調べて少しわかってきたのでそれについては、
「doxygen + graphviz で日本語を使った絵をドキュメントに埋め込む」の方に
コメントします。
投稿者: PATIO (2006.06.15 午後 01:23)
未知の文字化けパターンを確認しましたので、ご報告させていただきます。
2Byte目が0x40、0x5b時に文字化けすることが判明しました。
※0x5b時は特定の条件のみ化けるようです。
憶測ですが、文字コード表(ISO)で★(各国選択)コードがうまく変換できないのでは?
(2Byte目が0x23,0x24,0x40,0x5b,0x5c,0x5d,0x5e,0x7b,0x7c,0x7d,0x7e)
今回化けて表示された文字列は、
①
RFJDキュー開放
↓
RFJDキュ・/b>[開放
②
ワークバッファ→
↓
ワークバッフメィ
このようになりました。
0x40については、
else if ( inputString[inputPosition] == '@' ) {
// 漢字の2バイト目が 0x40 のとき特別扱いが必要
*buf++ = '\\';
c++;
}
このコードを足すことである程度対応できていましたが、全角スペースがある場合、'―'に置き換えてしまうようです。
(全角スペースを使わなければ良いのですが。。。)
何か今現在で分かっていましたら、対応方法等、ご教授お願いいたします。
投稿者: mitsu (2006.07.19 午後 06:48)
0x40,0x5bのときに問題が出るんですね。こちらでも調べてみます。「全角スペースがある場合、'―'に置き換えてしまう」のは
「漢字の2バイト目が 0x40 のとき」の特別な処理を入れたのが原因ということですか。
それとは別に iconv が置き換えてしまう文字がいくつかあります(例えば、'~')ので、その辺も何か対策した方がいいのかもしれません。置き換えられてしまった結果が許容範囲かどうかは、人によって違うとは思いますが、気になる人は気になると思います。
投稿者: tsupo (2006.07.20 午後 12:38)
お返事ありがとうございます。
また、貴重な情報ありがとうございます。
こちらでも引き続き調査を進めたいと思います。何か分かりましたらまた書き込ませていただきます。
投稿者: mitsu (2006.07.21 午後 05:18)