低レベルなヒトの覚え書き

●Another HTML-lintとPerl for Win32の話。ていうか、DOSマシンでも使えました


7. DJGPP版のPerlを使って、WindowsのDOS窓で、Another HTML-lintを動かす

(1) DJGPP版のPerlのインストール

先に紹介したように、DJGPP版のPerlには、5.004_02と5.005_03の2種類のバージョンがあります。 どちらのパッケージも、特別なインストール作業は必要としません。 基本的には、zipファイルを展開すれば、それで終わりです。 マニュアルで指示されている、lib\perl5\Config.pmの修正などは、やってもやらなくても、関係ないみたいです。

[追記]
現在では、バージョン5.8.8とか5.6.1のバイナリも利用できるようになっています。 このうち、少なくとも5.6.1のほうは、上の2つと同様、特別なインストール作業は必要ないようです。

(2) Jcode.pmのインストール

Jcode.pmとは、小飼弾さんが制作、公開しておられる、Perlの拡張ライブラリです。 基本的には、5.8系よりも前のPerlで(ときには5.8系以降でも)、日本語の文字を正しく処理するために使われます。
Another HTML-lintでは、Perlのバージョンに関わりなく、必須とされています。
バージョン2.00以降のJcode.pmは、5.005系以降のPerlでなければ利用できません。 バージョン0.88までなら、5.004のPerlでも使えます。
インストールの手順については、マニュアルを参照してください。 と、いいたいところですが、2.00以降のマニュアルでは、その辺の説明が省略されていたりします。 実際は、0.88までと同様、「Jcode.pm」そのものと「Jcode」ディレクトリの一式を、Perlの「site」ディレクトリにコピーするだけでいいようです(DJGPP版の場合は、lib\perl5\site)。

[URL]

(3) Another HTML-lintのインストール

基本的なことは、ご本家のページとか、よくできた解説ページがほかにあるので、そちらを参照してください。 ここでは、次の3点に絞って説明します。
1つ目は、パッケージの選択。
2つ目は、htmllint.envの設定。
3つ目は、DJGPP版のPerlとAnother HTML-lintの相性問題です。

まず、Another HTML-lint(以下、HTML-lint)のパッケージには、いわゆるフルパッケージのほかに、ファイルの種類別に4分割されたものが用意されています。 必要のないファイルを排除したり、ファイルの種類別にディレクトリを分けたい場合は、後者のほうが便利です。
4分割されたパッケージのうち、HTML-lintの動作に絶対不可欠なのは、「core」と「rul」の2つだけです。 「html」は、CGIとしての動作には必要ですが、コマンドラインでの動作には不要です。 ただ、このパッケージに関しては、ご本家のサイトと同じhtmlファイルが含まれているので、一種のマニュアルと見なすこともできます。 「dtd」は、いかなる動作にも必要ありません。
ちなみに、筆者が試してみたところでは、最低限、以下のようなファイルがあれば、コマンドラインでの動作には支障ないみたいです。

[表11]
 ----------------------------------------------------------
    種別         ファイル
 ----------------------------------------------------------
  「core」      htmllint
                htmllint.env(註1)
                htmllint.pm
                RFC2396 .pm
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  「rul」       charsets.rul
                colortable.rul(註2)
                common  .rul
                それぞれのDOCTYPEに応じた規則ファイル(註3)
 ----------------------------------------------------------
   註1: 不要な場合もあります(後述)。
   註2: 経験上は不要ですが、マニュアル(というか、download.html)では必要ということになってます。
   註3: html401-transitional.rulなど。

パッケージの展開を済ませて、ディレクトリの配置が決定したら、htmllintenvを編集して、htmllint.envを作成します。
その際、HTML-lintをCGIとして動かすつもりがなければ、「$RULEDIR」以外の項目は放っておいてかまいません(極端な話、削除してもいい)。
また、上の条件に加えて、HTML-lintのファイルをすべて同じディレクトリに置いている場合は、原則として、htmllint.env自体が不要となります(htmllintenvの冒頭のコメント参照)。

最後に、DJGPP版のPerlとHTML-lintの相性問題について述べます。 これまでのところ、2つの不具合が判明しています。
その1つは、本来ならばhtmllint.envを省略できるはずの状況でも、htmllint.envの省略が許されないという問題。
もう1つは、HTML-lintを起動するとき、あらかじめ特定の場所にカレントディレクトリを移動しておかないと、起動に失敗してしまうという問題です。
このうち1つ目の問題については、素直にhtmllint.envを用意すれば済むことなので、それほど実害はないと思います(というか、原因がわからないので、筆者には、ほかにどうしようもありません)。
2つ目の問題に関しては、話が長くなるので、項目をあらためて説明します。

註: 一連の検証作業で使用したHTML-lint(htmllint.pm)のバージョンは、3.23です。 DJGPP版のPerlについては、5.004_02と5.005_03の両方を使用しました(いずれもCPANで直接配布されているもの)。 なお、どちらのバージョンのPerlを使っても、結果に変わりはありませんでした。

[追記]
同様の相性問題は、以下の組み合わせについても確認されています。
HTML-lintの3.27に、DJGPP版の5.004_02と、5.6.1。
HTML-lintの3.28に、DJGPP版の5.005_03。

[追記(その2)]
DJGPP版の5.6.1に関しては、ほかにもうひとつの問題があります。 詳しくは、次の項目の「追記」と、こちら (v-clmn4.htm) を参照してください。

(4) htmllintの修正 -- Can't locate hogehoge.pm --

DJGPP版のPerlを使って、HTML-lint(Another HTML-lint)を動かすためには、起動スクリプトのhtmllintを改造する必要があります。 オリジナルのままでは、HTML-lintを任意のディレクトリから起動することができません。 起動のコマンドを入力する時点で、HTML-lint(の「core」)がインストールされている場所をカレントディレクトリにしておかないと、「htmllint.pmが見つからない」といわれてしまいます。
一般に、Perlのスクリプトのなかで別のスクリプトを呼び出すときは、ファイルの名前をいちいちフルパスで指定することは好まれません。 ファイルの所在についての情報は、@INCという特殊な変数(DOSの環境変数のPATHみたいなもの)を介して受け渡すことが多いようです。 HTML-lintの起動スクリプトも、この方式を採用しています。
ところで、HTML-lintの起動スクリプトでは、@INCに情報を登録する際、肝心の情報そのもの(対象となるファイルの所在)も、自力で準備する仕組みになっています。 具体的には、Basename.pm(lib\perl5\File\Basename.pm)という標準ライブラリのなかの「fileparse」というサブルーチンを使って、自分自身がインストールされている場所を確定しているのですが、DJGPP版のPerlを使用した場合は、どういうわけか、このサブルーチンが正常に機能しません。
これを解決するためには、少なくとも2つの方法があります。
1つは、fileparseと無関係に、正確な情報を@INCに登録してしまうこと。
もう1つは、fileparseのオプションを操作して、その動作を制御してやることです。

[リスト9]
 | # push (@INC, 'c:\htmllint');       # パターン1
 | use File::Basename;                 # オリジナルの5行目(パターン2)
 | # fileparse_set_fstype(MSDOS);      # パターン2
 | push @INC => [&fileparse($0)]->[1]; # オリジナルの6行目(パターン2)

パターン1の場合、オリジナルの5行目と6行目(リストの2行目以下)は削除してかまいません。
ディレクトリを指定する部分は、「c:/htmllint」とか「c:/htmllint/」とか「c:\htmllint\\」という書き方もできます。 最後に「\」をつけるときは、2重にしないとエラーになります(エスケープの関係)。 ちなみに、この辺はhtmllint.envでも同様です。
パターン2の場合は、オリジナルの5行目と6行目もそのまま残します。
OSの種類を指定する部分は、「MSDOS」のかわりに「MSWin32」としてもかまいません。 とりあえず、HTML-lintに関する限りは、どちらでも特に違いはないようです。
以上の対策(いずれか一方)により、DJGPP版のPerlでも、任意のディレクトリからHTML-lintを起動できるようになります。

[追記]
バージョン5.6.1のDJGPP版Perlを使って、HTML-lintの起動スクリプト(上記の対策済み)を実行すると、「Basename.pmが見つからない」といわれてしまいます。
このBasename.pmは、Perlの標準ライブラリの一部なので、本来、その所在については、デフォルトの状態で、@INCに登録されていることが望まれます。 DJGPP版の5.004_02などの場合は、個々のユーザーの環境にあわせて、自動的に設定が変更されるようになっているのですが、DJGPP版の5.6.1の場合は、そうではないようです。
このエラーを解決するためには、何よりもまず、正しい情報を@INCに書き込むことが必要です。 方法はいくつかありますが、いちばん簡単なのは、環境変数の「PERLLIB」(もしくは、PERL5LIB)を利用することだと思います。
なお、この問題に関しては、こちら (v-clmn4.htm) も参照してください。

◆実験

スクリプトファイルの検索パス(@INC)の設定のあり方を検証する実験です。
リスト10を材料として、処理方法(4パターン)とPerlの種類(DJGPP版とnsPerl)による結果の違いを比較しました。
Perlのバージョンは、いずれも5.005_03。 DJGPP版は「C:\DJPERL」、nsPerlは「C:\NSPERL」にインストール。 材料のスクリプトは「C:\EXP」に置かれ、コマンドは「C:\」から実行されました。

[リスト10]
 | # use File::Basename;                 # パターン1,2,3
 | # fileparse_set_fstype(MSDOS);        # パターン2
 | # fileparse_set_fstype(MSWin32);      # パターン3
 | # push @INC => [&fileparse($0)]->[1]; # パターン1,2,3
 | # push (@INC, 'c:\exp');              # パターン4
 | $a=0;
 | while(@INC[$a] ne "") {
 |   printf("%d %s\n", $a, @INC[$a]);
 |   $a++;
 | }

まず、それぞれの@INCのデフォルトは、こうなっていました。

[表12]
 ----------------------------------------------------------------------
  @INC            nsPerl                             DJGPP版
 ----------------------------------------------------------------------
  [0]     C:\NSPERL\lib/MSWin32-x86           c:/djperl/lib/perl5
  [1]     C:\NSPERL\lib                       c:/djperl/lib/perl5/site
  [2]     C:\NSPERL\site\lib/MSWin32-x86      c:/djperl/lib/perl5/site
  [3]     C:\NSPERL\site\lib                  .
  [4]     .
 ----------------------------------------------------------------------

パターン別の処理によって追加されたディレクトリは、次のとおり。

[表13]
 -------------------------------------------------
          パターン             nsPerl     DJGPP版
 -------------------------------------------------
  1(fileparse: OS指定なし)     c:\exp\    ./
  2(fileparse: MSDOS指定)      c:\exp\    c:\exp\
  3(fileparse: MSWin32指定)    c:\exp\    c:\exp\
  4(直接push)                  c:\exp     c:\exp
 -------------------------------------------------

こうしてみると、DJGPP版のほうは、Perlのソースを(DOS向けの調整なしに)そのままコンパイルしただけなんじゃないかという気もしてきますが、真偽のほどはわかりません。

[追記]
バージョン5.6.1のDJGPP版Perlの@INCについては、こちら (v-clmn4.htm) も参照してください。

[追記(その2)]
見ればわかるとは思いますが、リスト10の前半部分は、HTML-lintの起動スクリプトの内容を参考にしたものです(当然、リスト9もそう)。
あと、6行目以降の部分については、「print join("\n",@INC);」とするだけで、ほぼ同じ結果が得られるようです(perlfaq2の「I copied the Perl binary from one machine to another, but scripts don't work.」を読んでて見つけました)。

→トップ , →前(hlin6) , →次(hlin8)


R.13: 2008/03/18
Copyright (C) 2005-2008 A.Satoshi