NKF 2.0.6 のその前に2005年11月09日 23時46分01秒

ここのところ成瀬さんにNKF のUNICODEマッピングに関することをいろいろと
教えてもらっています。

ところで、JISX0208 の範囲の文字だけ各ツールで変換してみたところ

                                      Perl
JIS  EUC-JP    JISX0208  Encode   Iconv    Iconv         nkf
X208              *1     EUC-JP   EUC-JP   EUC-JP-MS    2.0.15
---------------------------------------------------------------
213D 0xa1bd ―  U+2015 : U+2015 : U+2014 : U+2015     : U+2015
2140 0xa1c0 \  U+005c : U+ff3c : U+ff3c : U+ff3c     : U+ff3c
2141 0xa1c1 ~  U+301c : U+301c : U+301c : U+ff5e     : U+301c
2142 0xa1c2 ∥  U+2016 : U+2016 : U+2016 : U+2225     : U+2016
215D 0xa1dd -  U+2212 : U+2212 : U+2212 : U+ff0d     : U+2212
2171 0xa1f1 ¢  U+00a2 : U+00a2 : U+00a2 : U+ffe0     : U+00a2
2172 0xa1f2 £  U+00a3 : U+00a3 : U+00a3 : U+ffe1     : U+00a3
224C 0xa2cc ¬  U+00ac : U+00ac : U+00ac : U+ffe2     : U+00ac

*1 http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/JIS0 208.TXT のマッピングによる変換
という結果が得られました。
Perl Encode の EUC-JP や Iconv の EUC-JP は JIS0208.TXT
のマッピングかと思っていましたが、違うのですね。
今頃知りました。

んー。こんなに違うと嫌ですね。
結局、mknmz では Text::Iconv を、namazu は libiconv(glibc の iconv) を
使うというようにツールを統一しないといけないかもしれません。

それにしても Perl の Encode のマッピングは結構謎です。
そのため、Encode を mknmz で使ってしまうと、namazu 側で困るかもしれません。
# あぁ、厄介。

テキスト整形に関して2005年11月01日 14時38分18秒

> 前処理として分かち書きの前にテキストを整形します。
>
> また、
> ・行頭、行末の空白文字を削除
> ・改行は日本語の単語の区切とは見なさない。(改行を連結)
> ・空白行は単語の区切とする
> というようにしました。

という上記に関係する処理ですが、実は gfilter::line_adjust_filter と思想的には同じものでした。(処理は多少異なる)

gfilter::line_adjust_filter と重複するのは何ですので、将来的にはgfilter::line_adjust_filter を廃止し、mknmz 側で処理するようにしたいと思います。

これは、

- plain テキストでは処理が通らないのはまずい
- 全てのフィルタで処理するものを各フィルタから呼び出さないといけないのは面倒

という理由によるものです。

Re: ワイド文字のAPI2005年10月25日 07時21分34秒

perlrun の -C を見ると

(In Perls earlier than 5.8.1 the -C switch was a Win32-only switch that enabled the use of Unicode-aware ``wide system call'' Win32 APIs. This feature was practically unused, however, and the command line switch was therefore ``recycled''.)

(5.8.1より前のperlでは-CスイッチはWin32 APIのunicodeを意識した「wide system call」の使用を有効にするwin32専用のスイッチだった。この機能は実質的に使われなかったので、その結果コマンドラインスイッチはリサイクルされた。)

となっており、-C が 5.8.1 以降変更になってしまっています。
${^WIDE_SYSTEM_CALLS} の方はそのまま使えるのかは、まだ確認していませんが、要注意です。

cmd.exe /d オプション2005年10月25日 06時53分56秒

「Perl 5.8.1 では system(), バッククオート, 及び, 外部プログラムへのパイプ等で内部で使用する cmd.exe シェルの実行時に /d スイッチを使います. その他のスイッチは, 外部プログラムを実行するときに通常望まれていないと考えられるレジストリからの AutoRun コマンドの実行を無効化します. もし以前の振る舞いを維持したいのなら PERL5SHELL 環境変数に cmd /x/c と設定して下さい.」

とのことです。util::syscmd() の内部から cmd.exe を呼び出す際には /d オプションを付けた方が良いかもしれません。

しかし、cmd /x/c の /x とは何でしょう。

Re: ワイド文字のAPI2005年10月24日 19時57分40秒

Perl + Win32 環境で

${^WIDE_SYSTEM_CALLS} = 1;

とすると、ワイド文字の API (Unicode 版 Win32 API)を使います。

File::Find でも CP932の第二バイトが 0x5c の文字で終わるディレクトリも扱えますし、-f や -d も問題なく動作します。 (こっちは確認済み)

Win32 の $CodingSystem は全世界共通で UTF-8 として扱えば良いということになります。

この時、ディレクトリ名、ファイル名は UTF-8 になるという点だけは気にしなければなりません。
UTF-8 版 Namazu との親和性は高いと思います。

ワイド文字のAPI2005年10月24日 19時45分07秒

Perl のドキュメントを調べていると、「Windows プラットホームにおいては, -C コマンドラインスイッチが使われているか, ${^WIDE_SYSTEM_CALLS} グローバルフラグが 1 に設定されているのなら, すべてのシステムコールは対応するワイド文字の API を使います.」と書かれていました。

この機能を Windows で使うと、ワイド文字のAPIが使われるため、ファイル名の処理に直接ワイド文字が使えることになります。
FAT32,NTFS 共 ロングファイル名は Unicode で記録されますから、ANSI 文字でファイルのアクセスをするよりも直接ワイド文字でアクセスする方が安全です。
ANSI文字、日本語の場合 CP932 なら '\' 0x5c がいろいろと厄介な問題*1を起こしますが、ワイド文字で扱うならばそのような厄介な問題は避けられます。

*1 例えば、CP932 の 2バイト目が 0x5c の文字で終わるディレクトリ名の場合、パス区切りと誤認します。

Perl 5.6 以降で有効か?

大文字と小文字2005年10月24日 08時31分59秒

libnmz には isalpha, isalnum 等のローケルに依存して動作が異なる関数が使われています。
これは、ローケルによって動作が異なるため、注意が必要です。
(ASCII 7bit 文字を引数に渡す場合は問題ありません。)

strcasecmp, strncasecmp もローケル依存のため、注意が必要です。

toupper, tolower は撲滅したはずです。もし、toupper, tolower が使われている箇所があれば、それはバグです。

strcasecmp, strncasecmp がないシステムのために strcasecmp.c, strncasecmp.c は nmz/ に含まれますが、ここでは tolower が使われる可能性があるので、注意が必要です。

壊れたインデックスを調査するには2005年10月18日 13時19分04秒

Namazu はときより何らかの理由により、インデックスが壊れることがあります。
主に各種ソフトウェアの不具合によるものですが、具体的には分かりません。また、インデックスが壊れていても気づかないことも多々あります。
このため、インデックスが壊れているか否か検証する方法があるとよさそうです。
そうすれば、インデックスを壊す原因を突き止めやすくなるでしょう。

1. NMZ.i と NMZ.ii の整合性
NMZ.ii の値と、NMZ.i のデータの整合性は検証可能です。
- NMZ.ii のデータ(オフセット)は小さい順に並んでいます。
- NMZ.ii の最初の値は 0 です。
- NMZ.ii の最後の値をオフセットとした NMZ.i の値と先のオフセットを加算すると、NMZ.i のファイルサイズです。
- NMZ.i の単語データ長(+4)を累積していくと NMZ.ii の値と一致するかで検証可能です。(行区切りのチェック)
- NMZ.i の文書IDが小さいもの順に並んでいる。(ただし差分のため、チェックにはあまり有効ではない)

注意) BER 圧縮に注意すること

2. NMZ.w と NMZ.wi の整合性
- 単語ごとに改行が含まれるため、改行の個数が単語の個数です。
- NMZ.w の単語数と、NMZ.wi のデータ数は一致します。
- NMZ.wi のデータ(オフセット)は小さい順に並んでいます。
- NMZ.wi の指す位置はNMZ.wの単語の先頭文字です。 (行区切りのチェック)
- 単語の並びは昇順です。
- nul 文字や制御文字(改行を除く)は含まれません。
- EUC-JP 以外は含まれないはずですが、一部文字化けした単語がゴミとして含まれる可能性はあります。

3. NMZ.w* と NMZ.i* の整合性
- NMZ.i の単語数と NMZ.w の単語数は一致します。

4. NMZ.p と NMZ.pi の整合性
- NMZ.pi は必ず 262144 バイト(2^16 * sizeof(int))です。
- NMZ.pi のデータ(オフセット)は小さい順に並んでいます。
- NMZ.pi の最初の値は 0 です。
- NMZ.pi の最後の値をオフセットとした NMZ.p の値と先のオフセットを加算すると、NMZ.p のファイルサイズです。
- NMZ.p のデータ長(+4)を累積していくと NMZ.pi の値と一致するかで検証可能です。(行区切りのチェック)

5. NMZ.field.xxx と NMZ.field.xxx.i の整合性
- NMZ.w と NMZ.wi の整合性とほぼ同じ

6. 文書IDの整合性
- NMZ.i に含まれる文書IDは、最大文書IDまでです。
- NMZ.p に含まれる文書IDは、最大文書IDまでです。
- NMZ.t は全文書数分のデータです。
- NMZ.field.xxx は有効な全文書数分のデータです。
- NMZ.status の files は有効な全文書数です。
- NMZ.r は全文書数、有効な全文書数の両方の情報が含まれます。

7. 単語数の整合性
- NMZ.status の keys と NMZ.w の単語数は一致します。(文書削除後も)

8. テキストファイルの妥当性
- UNIX 改行
- EUC-JP (除く NMZ.r)

これらをきちんとチェックするツールがあるとインデックスが壊れているかどうか簡単に調べられて便利だと思います。


データのチェックのため、レコード単位でCRC 等をインデックスに含めるのが簡単で良いのかもしれません。

追記:
pnamazu に tool2/nmzcheck.pl がありました。

この文書は、不定期に更新します。

libnmz 関係の話2005年10月06日 06時00分38秒

libnmz (nmz.dll) を利用する場合、たくさんのヘッダーファイルをインクルードする必要があります。これは非常に不便です。

メインのヘッダ libnmz.h と、オプション的なものを後2つぐらいまでに整理するべきです。(内部でたくさんのヘッダを使うのは良いとしても)

また、struct nmz_names NMZ、struct nmz_files Nmz 構造体を extern するのはやめ、libnmz 内部でメモリを動的に確保、開放する外部関数を用意した方が良いでしょう。

libnmz は LGPL ではなく GPL なため、ライセンス的に利用しにくいライブラリとなっています。GPL のコードを利用していることもありますし、著者が沢山いらっしゃるので今更 LGPL にライセンスを変更するのは難しいと思われます。
そのためまずは libnmz を使った xmlnamazu コマンド(GPL)を新たに作り、それを呼び出す libnmz LGPL 版(libnmz GPL のラッパとなる)を作ることで、何とか LGPL として使用できるライブラリを用意したいと思います。

将来的には、新たに一から書き直して LGPL 版の libnmz を作りたいと思います。

NG は Next Generation2005年10月06日 05時56分26秒

新しいカテゴリ NG を作りました。
このNGは Next Generation の略で、No Good でも Nihongo micro Gnu emacs の略でもありません。

Namazu の次世代(バージョンは不明)に関して思いついたことを書こうと思います。