Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dvi2tty, dvispc and dviasm: FNTDEF before BOP #138

Open
3 of 4 tasks
aminophen opened this issue Mar 10, 2022 · 29 comments
Open
3 of 4 tasks

dvi2tty, dvispc and dviasm: FNTDEF before BOP #138

aminophen opened this issue Mar 10, 2022 · 29 comments
Labels

Comments

@aminophen
Copy link
Member

aminophen commented Mar 10, 2022

dvi2tty の GitHub に issue 機能がないようなのでこちらに書きます。

aminophen/dviasm#20 のとおり

  1. TeX で作った適当な DVI を dviasm でテキスト形式に変換
  2. そのテキスト形式を dviasm で DVI に戻す → (★)
  3. できた DVI (★) を dvispc でテキスト形式に変換 → (△)
  4. そのテキスト形式を dvispc で DVI に戻す → (☆)
  5. できた DVI (☆) を dvi2tty に与える

この手順を踏むと最後のステップ 5. で dvi2tty が Segmentation fault: 11 します。なお,途中の (★) で得られた DVI を dvi2tty に与えるとこれは

dvi2tty: Missing beginning-of-page command

というエラーで止まり [Return] を押下するまで終了しないようです。(私の環境固有?)


この問題は割と複雑で

  • dviasm が生成する DVI (★) は「最初の BOP より前に FNTDEF をまとめて置く」という挙動であること(※ 通常の TeX が作る DVI では「ページ内部で最初にフォントが使われる直前に FNTDEF を置く」のと異なる)
  • dvispc は「最初の BOP より前に書かれた FNTDEF を無視する」という挙動であること (△)

が絡んでいます。(★) の DVI は Knuthware の dvitype のみならず一般的な dvipdfmx, dvips でも問題なく処理できる正常なものです。一方,(☆) の DVI は dvipdfmx で処理できるが dvips でエラーになるという微妙なものです。

  • dvi2tty の改善事項(1):(☆) の DVI でも Segfault しないように
  • dvi2tty の改善事項(2):(★) の DVI を読めるように
  • dvispc の改善事項:(★) の DVI でも「最初の BOP より前に書かれた FNTDEF」を無視しないように
  • dviasm の改善事項:一般的な TeX の DVI に近づけられないか

これらを検討したいと思います。(特に dvi2tty の Segfault は優先度高い?)

@t-tk
Copy link
Collaborator

t-tk commented Mar 11, 2022

とりあえず私のところのdvi2tty には Issues を作りました。 https://github.com/t-tk/dvi2tty/issues
しかし、議論はここで続けましょう。
TeX Live 2022 のコードフリーズは日程的には過ぎ去っているので、そこに押し込むのは厳しいかなと思っています。
まずは調べてみます。

@t-tk
Copy link
Collaborator

t-tk commented Mar 11, 2022

こちらのWSL の ubuntu で試しました。
入力ファイル: texk/dvi2tty/dvi2tty-src/test/table.dvi
dviasm.py 20200918
dvispc Ver.20190206 (TeX Live 2019)

dviasm.py  -o table.dviasm table.dvi
dviasm.py  -o table-001.dvi table.dviasm
dvispc -s table-001.dvi  table-001.dvispc
dvispc -x table-001.dvispc table-002.dvi

table-001.dvispc は color special の情報ばかりのようです。
table-002.dvi を作成するところで
Write 0 byte (0 page): table-002.dvi
と言われます。table-002.dvi の中身は空になります。segfaultは再現できていません。
dvi2tty table-001.dvi では

dvi2tty: Missing beginning-of-page command

と警告が出てすぐに終了します。 [Return] の押下は不要です。
dvitype table-001.dvi は stdout にぞろぞろ出力が流れます。一応ちゃんと読めているようです。

@t-tk
Copy link
Collaborator

t-tk commented Mar 11, 2022

dvispcのオプションを間違えました。しかしやはりsegfaultは再現しません。

❯ dvispc -a table-001.dvi  table-001.dvispc

❯ dvispc -x table-001.dvispc table-002.dvi 
Max stack depth: 7 -> 6
Write 307064 byte (13 page): table-002.dvi

❯ dvi2tty test-002.dvi 
dvi2tty: Missing postamble

@aminophen
Copy link
Member Author

入力ファイル: texk/dvi2tty/dvi2tty-src/test/table.dvi

私も同じものを macOS で試しましたが,やはり最後のステップで dvi2tty が Segmentation fault: 11 します。自分でビルドしたもののみならず,macOS 用のプレテストのバイナリでも同様です。

@t-tk さんのところでは "dvi2tty: Missing postamble" のエラーが出るようですが,私の環境では

途中の (★) で得られた DVI を dvi2tty に与えるとこれは
dvi2tty: Missing beginning-of-page command
というエラーで止まり [Return] を押下するまで終了しない

という挙動のため,エラー出力がうまく行っていないことを疑っています。

@t-tk
Copy link
Collaborator

t-tk commented Mar 11, 2022

ざっと ChangeLog を読み直して振り返ってみましたが、
2016年3月に私がメンテナーになって ver6.0.0 を出して以来ほとんど触っていないし、
それ以前の2010年のver5.3.4 と ver6.0.0 の差分も FNTDEF と BOP の順番に関する解釈などは変わっていないので、
本Issueははるか昔からあるものと思います。

@t-tk
Copy link
Collaborator

t-tk commented Mar 11, 2022

やり直したらなぜか segfault が再現しました。
dvistuff.c, dochar() の fnt->flags の fnt が空で segfault が出るみたいです。

@t-tk
Copy link
Collaborator

t-tk commented Mar 11, 2022

とりあえず segfault が出る前にエラー出力して止める案 657634a です。

./dvi2tty: Fail to get font information

@aminophen
Copy link
Member Author

657634a

これだと無条件にエラー出力で止まるので if (fnt == NULL) とすべきと思います。

t-tk added a commit that referenced this issue Mar 11, 2022
@t-tk
Copy link
Collaborator

t-tk commented Mar 11, 2022

失礼しました。9e27316

@t-tk
Copy link
Collaborator

t-tk commented Mar 11, 2022

Karlさんから code freeze 宣言はまだ出ていませんが、これを入れさせてもらうかどうか。
バッファーオーバーランのようなものではないし、TeX family が出す dvi の形式ではこの segfault は出ないのでリスキーだとは感じないのですが。

@aminophen
Copy link
Member Author

TeX family が出す dvi の形式ではこの segfault は出ない

その通りだと思います。何か他にリビルドを要する機会がなければ入れなくて良いと思います。

@aminophen
Copy link
Member Author

フリーズ宣言が出ていないなか,HiTeX のコミットが8時間前 (r62619) で起こっているので急いでコミットしましょうか

@t-tk
Copy link
Collaborator

t-tk commented Mar 11, 2022

出来るならお願いします。

@aminophen
Copy link
Member Author

r62644. Karl さんにも伝えておきました。


Other issues: 私のところでエラー出力後に止まる現象はもう少しこちらで調べます。

@t-tk
Copy link
Collaborator

t-tk commented Mar 13, 2022

『dvi2tty の改善事項(2):(★) の DVI を読めるように』は 02ca4b8 で動きました。これでよいような気がします。

『(☆) の DVI でも dvi2ttyが読めるように』というのも試してみました。postambleにあるFNTDEFを上手く読めれば動くような気がしていますが、今のところ上手く出来ていません。

@aminophen
Copy link
Member Author

『dvi2tty の改善事項(2):(★) の DVI を読めるように』は 02ca4b8 で動きました。

ありがとうございます。良いと思います。

@t-tk
Copy link
Collaborator

t-tk commented Mar 15, 2022

私の理解では、FNTDEFの場所を整理すると

dvi PREとBOPの間 BOPの後 EOPとBOPの間 POSTの後 未対応のdviware
TeX出力 [※] × ×
※→dvispc出力 × ×
※→dviasm出力 [★] × × (dvi2tty:今回対応)
★→dvispc出力 [☆] × × × dvips, dvi2tty
仕様上可能 [◆] (dvi2tty:今回対応)

ソースを眺めてみたら確かにdvips, dvi2ttyはともにPOSTの後のFNTDEFは読んでいないようです。
その対応はしなくてよいかなと思っています。

大島先生のところのdviの解説を見ると※だけが合法で★は規格外のように受け取れます。
どこかに正式な仕様書はあるのでしょうか。

@h20y6m
Copy link
Collaborator

h20y6m commented Mar 15, 2022

正式な仕様かどうかわかりませんが、dvitype.web に以下のような記述があります。

Font definitions must appear before the first use of a particular font number.
Once font |k| is defined, it must not be defined again; however, we
shall see below that font definitions appear in the postamble as well as
in the pages, so in this sense each font number is defined exactly twice,
if at all. Like |nop| commands, font definitions can
appear before the first |bop|, or between an |eop| and a |bop|.

これを見ると★は合法で☆は不正ということになるのではないでしょうか。

@aminophen
Copy link
Member Author

DVI フォーマットの仕様書は https://ctan.org/tex-archive/dviware/driv-standard/level-0 にあります。ざっと見た感じでは @h20y6m さんがあげている dvitype.web と同じことが書かれています。

大島先生の「1. DVIファイルのフォーマット」の

DVIファイルは,ファイルの先頭が プリアンブル で,その後 ページ記述部 となり,最後に ポストアンブル があります.ページ記述部は各頁毎に分かれて独立した形になっています.

は DVI フォーマットの仕様書 A.1 の

A DVI file consists of a “preamble,” followed by a se- quence of one or more “pages,” followed by a “postamble.”

の和訳と思われます。今回の「BOP の前の FNTDEF」は想定されていないようですが,DVI フォーマットの仕様書 A.4 にも @h20y6m さん引用と同じ文があり,私も同じ理解です(つまり ★ は合法で ☆ は不正)。

@t-tk
Copy link
Collaborator

t-tk commented Mar 15, 2022

ありがとうございます。
そうすると★は対応する、☆は対応なしでよい、ということでよいですね。

@aminophen
Copy link
Member Author

aminophen commented Mar 15, 2022

FNTDEFの場所を整理すると

上で引用されている

font definitions can appear before the first |bop|, or between an |eop| and a |bop|.

という記述から,

  • PRE と BOPの間
  • ページ記述内:BOP と EOP の間
  • ページとページの間:EOP と BOP の間(← このパターンもある!)
  • POST の後

ですね。

@t-tk
Copy link
Collaborator

t-tk commented Mar 15, 2022

ページとページの間:EOP と BOP の間

dvi2ttyの今回のパッチ 02ca4b8 はこのパターンも対応できていそうです。偶然ですが。

@t-tk
Copy link
Collaborator

t-tk commented Mar 16, 2022

NOPもFNTDEFと同じような場所に挿入OKでした。
CTAN/dviware/driv-standard/level-0/dvistd0.pdf:

The pages appear in the order that they were generated, not in any particular numerical order.
If we ignore nop commands and fnt def commands  (which are allowed between any two commands in the file), 
each eop command is immediately followed by a bop command, or by a post command;

NOPがどこに入っても大丈夫というコードはdvi2ttyにはすでに含まれていました。
ec19ceb ではそこ skipnops()にFNTDEFの読み込みを移動させました。
dvipsの場合も似たようなループと関数 skipnop() になっていて、さらに XXX1~XXX4 も読み飛ばすようにしてあるようです。

t-tk added a commit that referenced this issue Mar 17, 2022
t-tk added a commit that referenced this issue Mar 17, 2022
t-tk added a commit that referenced this issue Mar 17, 2022
t-tk added a commit that referenced this issue Mar 17, 2022
@t-tk
Copy link
Collaborator

t-tk commented Mar 17, 2022

dvispc は 811e052 でオプション -a-x は一応動いているみたいですがdvispcの場合モードがいろいろあるのでエンバグしていないか不安です。

t-tk added a commit that referenced this issue Mar 18, 2022
@t-tk
Copy link
Collaborator

t-tk commented Mar 18, 2022

dvispc の現在のパッチは -aかつ-p でページ指定したとき、※の場合と★の場合は必要なフォント情報を拾うことが出来ていますが「ページとページの間:EOP と BOP の間」の場合に読み落としてしまいます。
EOPの後ろでNOPとFNTDEFを探すようになっています。ページ選択の場合、ページの先頭のBOPを探してそこからページを読み始めるのでその直前のFNTDEFは読めません。
私としてはこれ以上は難しく、ここまでにしようと思います。

@aminophen
Copy link
Member Author

dvispc の方も検討いただきありがとうございます。まだソースを理解できていないのと試してすらませんが,-a かつ -p の場合は「ページとページの間:EOP と BOP の間」に限らず,複数ページにまたがって同じフォントが使われるときは最初の登場ページ内で FNTDEF が現れて次のページでは現れないので,普通の TeX の DVI でも FNTDEF を読み落とすのではないかと思います。ページ間の FNTDEF を読もうとするのではなく,ポストアンブルの「FNTDEF 総集編」を持ってくるようにしないと難しそうですね。時間があれば考えます。

@aminophen
Copy link
Member Author

改めて考えると,dvispc の -a の機能はあくまで DVI → テキスト変換 だと考えれば,-p オプションは「BOP 〜 次の BOP までを忠実にプリントする」という今の仕様でも許される気がしてきました。dviselect もあるので dvispc -p でページ抽出する必然性はないですし。

% dviasm で生成した「最初の BOP の前に全ての FNTDEF が集められた DVI」を dviselect にかけると,TeX の DVI と同じ形式(ページ内部で最初にフォントが使われる場所に FNTDEF を置く)に変換されますし,複数ページにまたがって同じフォントが使われるときにも正しく FNTDEF が置かれます。

ad0dc14 までで

  • 最初の BOP の前にある FNTDEF はプリアンブルに付随して(つまり -pT の時に)プリントされる
  • EOP 〜 BOP の間にある FNTDEF は直前のページに付随してプリントされる

という改善をしていただきましたので,私としては満足です。

@t-tk
Copy link
Collaborator

t-tk commented Apr 9, 2022

dvi2tty, dvispcの更新を TeX Live svn r62985, r62986にコミットしました。

@aminophen
Copy link
Member Author

dvi2tty, dvispc の更新ありがとうございます。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants