(前回の続き)
DVI で Quine できた話
というわけで、先述の方針に従って、実際に「DVI で Quine する」やつを作ってみた。
[teqgen.tex](Quine 生成器)
! \catcode13=12! \toks0{\output{\setbox0\box255 \shipout\hbox{% \special{ps::(! \catcode13=12! \toks0{\the\toks0}% \noexpand\the\toks0\end)pop}}}}% \the\toks0\end
[teq.tcx](TCX ファイル)
0xf7 0x25
- TeX: Yet Another Quine on TeX (Gist:zr-tex8r)
これらのファイルをカレントディレクトリに置いて、次のコマンドを実行して得られる DVI ファイル teqgen.dvi が Quine のファイルになっている。以下の説明ではこのファイルを teq.tex に改名したものとする。
tex -output-comment="" -translate-file=./teq teqgen
この Quine の TeX ソースファイル teq.tex は(DVI ファイルでもあるので)バイナリファイルであり、その 16 進ダンプは以下のようになっている。
[teq.tex](16 進ダンプ)
00000000 F7 02 01 83 92 C0 1C 3B-00 00 00 00 03 E8 00 8B .......;........ 00000010 00 00 00 01 00 00 00 00-00 00 00 00 00 00 00 00 ................ 00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 00000030 00 00 00 00 00 00 00 00-FF FF FF FF EF B8 70 73 ..............ps 00000040 3A 3A 28 21 0D 5C 63 61-74 63 6F 64 65 20 31 33 ::(!.\catcode 13 00000050 3D 31 32 21 0D 5C 74 6F-6B 73 20 30 7B 5C 6F 75 =12!.\toks 0{\ou 00000060 74 70 75 74 20 7B 5C 73-65 74 62 6F 78 20 30 5C tput {\setbox 0\ 00000070 62 6F 78 20 32 35 35 20-5C 73 68 69 70 6F 75 74 box 255 \shipout 00000080 20 5C 68 62 6F 78 20 7B-5C 73 70 65 63 69 61 6C \hbox {\special 00000090 20 7B 70 73 3A 3A 28 21-0D 5C 63 61 74 63 6F 64 {ps::(!.\catcod 000000A0 65 20 31 33 3D 31 32 21-0D 5C 74 6F 6B 73 20 30 e 13=12!.\toks 0 000000B0 7B 5C 74 68 65 20 5C 74-6F 6B 73 20 30 7D 5C 6E {\the \toks 0}\n 000000C0 6F 65 78 70 61 6E 64 20-5C 74 68 65 20 5C 74 6F oexpand \the \to 000000D0 6B 73 20 30 5C 65 6E 64-20 29 70 6F 70 7D 7D 7D ks 0\end )pop}}} 000000E0 7D 5C 74 68 65 20 5C 74-6F 6B 73 20 30 5C 65 6E }\the \toks 0\en 000000F0 64 20 29 70 6F 70 8C F8-00 00 00 0F 01 83 92 C0 d )pop.......... 00000100 1C 3B 00 00 00 00 03 E8-00 00 00 00 00 00 00 00 .;.............. 00000110 00 00 00 01 F9 00 00 00-F7 02 DF DF DF DF DF DF ................
teq.tex(DVI ファイル)を dv2dt で逆アセンブルした結果は以下の通り。ここで special1 の引数の文字列は途中に改行が入っているが、この改行は全て CR(0x0D)である。
variety sequences-6 pre 2 25400000 473628672 1000 0 '' bop 1 0 0 0 0 0 0 0 0 0 -1 special1 184 'ps::(! \\catcode 13=12! \\toks 0{\\output {\\setbox 0\\box 255 \\shipout \\hbox {\\special {ps::(! \\catcode 13=12! \\toks 0{\\the \\toks 0}\\noexpand \\the \\toks 0\\end )pop}}}}\\the \\toks 0\\end )pop' eop post 15 25400000 473628672 1000 0 0 0 1 post_post 247 2 223 223 223 223 223 223
それでは、この teq.tex を使って Quine してみよう。次のように、先と同じオプションを付けて tex コマンドでコンパイルする。
tex -output-comment="" -translate-file=./teq teqgen
この結果として生成された DVI ファイル teq.dvi は元の teq.tex と完全に(バイナリで)一致する。
[Unix 系のシェル]
# cmp teq.tex teq.dvi # ←一致しているので何も表示されない
C>fc /B teq.tex teq.dvi ファイル teq.tex と TEQ.DVI を比較しています FC: 相違点は検出されませんでした
ちなみに、DVI の中に含まれる special 命令は正当な PostScript special 命令であるので、dvips や dvipdfmx の入力として通るようになっている(ただし結果は白紙であるが)。