-
Notifications
You must be signed in to change notification settings - Fork 6
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
[(u)pTeX] 禁則テーブルのハッシュ検索バグ #113
Comments
とりあえず試してみているコード: --- ptex-base.ch.1~ Thu Feb 18 11:48:14 2021
+++ ptex-base.ch Sat May 15 13:45:47 2021
@@ -6646,8 +6646,8 @@
@ @<Declare procedures needed in |scan_something_internal|@>=
function get_kinsoku_pos(c:KANJI_code; n:small_number):pointer;
label done, done1;
-var p,s:pointer;
-begin s:=calc_pos(c); p:=s;
+var p,pp,s:pointer;
+begin s:=calc_pos(c); p:=s; pp:=no_entry;
@!debug
print_ln; print("c:="); print_int(c); print(", p:="); print_int(s);
if p+kinsoku_base<0 then
@@ -6656,16 +6656,19 @@
gubed
if n=new_pos then
begin repeat
- if (kinsoku_type(p)=0)or(kinsoku_type(p)=kinsoku_unused_code)
- or(kinsoku_code(p)=c) then goto done;
+ if kinsoku_code(p)=c then goto done; { found, update there }
+ if kinsoku_type(p)=0 then { no further scan needed }
+ begin if pp<>no_entry then p:=pp; goto done; end;
+ if kinsoku_type(p)=kinsoku_unused_code then
+ if pp=no_entry then pp:=p; { save the nearest unused hash }
incr(p); if p>255 then p:=0;
until s=p;
- p:=no_entry;
+ p:=pp;
end
else
begin repeat
- if kinsoku_type(p)=0 then goto done1
- else if (kinsoku_type(p)<>kinsoku_unused_code)and(kinsoku_code(p)=c) then goto done;
+ if kinsoku_type(p)=0 then goto done1;
+ if kinsoku_code(p)=c then goto done;
incr(p); if p>255 then p:=0;
until s=p;
done1: p:=no_entry; |
禁則テーブルのほかに INHIBIT テーブルも同様なはずなので更新 ↓ --- ptex-base.ch.1~ Thu Feb 18 11:48:14 2021
+++ ptex-base.ch Sat May 15 14:44:20 2021
@@ -6574,19 +6574,23 @@
@ @<Declare procedures needed in |scan_something_internal|@>=
function get_inhibit_pos(c:KANJI_code; n:small_number):pointer;
label done, done1;
-var p,s:pointer;
-begin s:=calc_pos(c); p:=s;
+var p,pp,s:pointer;
+begin s:=calc_pos(c); p:=s; pp:=no_entry;
if n=new_pos then
begin repeat
- if (inhibit_xsp_type(p)=inhibit_unused)or(inhibit_xsp_code(p)=0)
- or(inhibit_xsp_code(p)=c) then goto done;
+ if inhibit_xsp_code(p)=c then goto done; { found, update there }
+ if inhibit_xsp_code(p)=0 then { no further scan needed }
+ begin if pp<>no_entry then p:=pp; goto done; end;
+ if inhibit_xsp_type(p)=inhibit_unused then
+ if pp=no_entry then pp:=p; { save the nearest unused hash }
incr(p); if p>255 then p:=0;
- until s=p; p:=no_entry;
+ until s=p;
+ p:=pp;
end
else
begin repeat
- if inhibit_xsp_code(p)=0 then goto done1
- else if (inhibit_xsp_type(p)<>inhibit_unused)and(inhibit_xsp_code(p)=c) then goto done;
+ if inhibit_xsp_code(p)=0 then goto done1;
+ if inhibit_xsp_code(p)=c then goto done;
incr(p); if p>255 then p:=0;
until s=p;
done1: p:=no_entry;
@@ -6621,6 +6625,7 @@
begin scan_int; q:=get_inhibit_pos(tokanji(cur_val),cur_pos);
cur_val_level:=int_val; cur_val:=inhibit_none;
if q<>no_entry then cur_val:=inhibit_xsp_type(q);
+if cur_val>inhibit_none then cur_val:=inhibit_none;
end
@ The \.{\\prebreakpenalty} is used to specified amount of penalties inserted
@@ -6646,8 +6651,8 @@
@ @<Declare procedures needed in |scan_something_internal|@>=
function get_kinsoku_pos(c:KANJI_code; n:small_number):pointer;
label done, done1;
-var p,s:pointer;
-begin s:=calc_pos(c); p:=s;
+var p,pp,s:pointer;
+begin s:=calc_pos(c); p:=s; pp:=no_entry;
@!debug
print_ln; print("c:="); print_int(c); print(", p:="); print_int(s);
if p+kinsoku_base<0 then
@@ -6656,16 +6661,19 @@
gubed
if n=new_pos then
begin repeat
- if (kinsoku_type(p)=0)or(kinsoku_type(p)=kinsoku_unused_code)
- or(kinsoku_code(p)=c) then goto done;
+ if kinsoku_code(p)=c then goto done; { found, update there }
+ if kinsoku_type(p)=0 then { no further scan needed }
+ begin if pp<>no_entry then p:=pp; goto done; end;
+ if kinsoku_type(p)=kinsoku_unused_code then
+ if pp=no_entry then pp:=p; { save the nearest unused hash }
incr(p); if p>255 then p:=0;
until s=p;
- p:=no_entry;
+ p:=pp;
end
else
begin repeat
- if kinsoku_type(p)=0 then goto done1
- else if (kinsoku_type(p)<>kinsoku_unused_code)and(kinsoku_code(p)=c) then goto done;
+ if kinsoku_type(p)=0 then goto done1;
+ if kinsoku_code(p)=c then goto done;
incr(p); if p>255 then p:=0;
until s=p;
done1: p:=no_entry; |
上のコメントのパッチを適用した Win32 バイナリを置いてみます → ptex-new.zip |
さらに \tracingassigns 用のコードも詳しくしてみる(上への追加) → ptex-new-2.zip --- ptex-base.ch.1~ 2021-02-18 11:48:14.000000000 +0900
+++ ptex-base.ch 2021-05-15 20:41:11.327346800 +0900
@@ -1249,10 +1249,27 @@
begin print_esc("xspcode"); print_int(n-auto_xsp_code_base);
end
else if n<kinsoku_base then
- begin print("(inhibitxspcode table) "); print_int(n-inhibit_xsp_code_base);
+ begin print("inhibitxspcode table "); print_int(n-inhibit_xsp_code_base);
+ print(", type=");
+ case eq_type(n) of
+ 0: print("both"); { |inhibit_both| }
+ 1: print("before"); { |inhibit_previous| }
+ 2: print("after"); { |inhibit_after| }
+ 3: print("none"); { |inhibit_none| }
+ 4: print("unused"); { |inhibit_unused| }
+ end; {there are no other cases}
+ print(", code");
end
else if n<kansuji_base then
- begin print("(kinsoku table) "); print_int(n-kinsoku_base);
+ begin print("kinsoku table "); print_int(n-kinsoku_base);
+ print(", type=");
+ case eq_type(n) of
+ 0: print("no");
+ 1: print("pre"); { |pre_break_penalty_code| }
+ 2: print("post"); { |post_break_penalty_code| }
+ 3: print("unused"); { |kinsoku_unused_code| }
+ end; {there are no other cases}
+ print(", code");
end
else if n<lc_code_base then
begin print_esc("kansujichar"); print_int(n-kansuji_base);
@@ -1412,7 +1429,10 @@
tats
@y
else if n<kinsoku_penalty_base then @<Show equivalent |n|, in region 6@>
-else if n<=eqtb_size then print("kinsoku")
+else if n<=eqtb_size then begin
+ print("kinsoku table "); print_int(n-kinsoku_penalty_base);
+ print(", penalty="); print_int(eqtb[n].int);
+ end
else print_char("?"); {this can't happen either}
end;
tats |
とりあえず aminophen さんの 2 パッチを h-kitagawa@8039073 に入れておきました. |
本 issue を Pull request にした #120 をマージしました。
なお,r59701 でバージョンを p3.9.1 にしています。 |
TeX Live 2024 の (e)(u)ptex で euptexdir/tests/kinsoku_table.tex を走らせると Segmentation fault: 11 する件について,どうやら 2022-12-12 r65246--65248 で禁則テーブルなどのサイズが 256→1024 に拡大された時(このあたり)からのようです。これが
r72333 で修正されたらしいのですが,今度はテーブルが 256 文字しか登録できなくなってしまったようです? %#!euptex -ini -etex
\let\dump\relax
\input plain
\newlinechar`^^J
% 無駄に256個埋める
\count200="10000
\loop\ifnum\count200<"10100\relax
\omathchardef\X=\the\count200
\message{\meaning\X: \the\prebreakpenalty\count200^^J}
\prebreakpenalty\count200=\count200
\message{\meaning\X: => \the\prebreakpenalty\count200^^J}
\advance\count200 by 1
\repeat
% 257個目
\prebreakpenalty`、=100
\bye
% => ! KINSOKU table is full!!. |
kinsoku_type(k) が 0<=k<=255 の場合のみ 0 に初期化されている? |
はい,そうなのですが,そうなったのは r72333 で意図的なようで…。??? 恐らく
を直したとされる r72333 が正しい修正策ではなく,見た目上 segv しなくなったけれども 256〜1023 の初期化が消えてしまったものかと。 |
私の手元では euptex -ini -etex で先ほどの例を走らせた時
となりました。 |
eqtb[] の kinsoku_penalty_base 以降の場所にペナルティの値を格納するようですが,この部分を 256 -> 1024 と拡大するのを忘れていたようです. |
なるほど。ありがとうございます。 こちらについては |
試していませんが,同様に移動してよいかと思います(\inhibitxspcode 周りについては別テーブルがないので). |
ご指摘いただいた通りと思います。
|
ありがとうございます。r73803 で修正をコミットしました。 |
https://oku.edu.mie-u.ac.jp/tex/mod/forum/discuss.php?d=3113 を参照。
ptex-base.ch の
get_kinsoku_pos
関数の assignment における挙動が変だと思います。The text was updated successfully, but these errors were encountered: