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

[(u)pTeX] 禁則テーブルのハッシュ検索バグ #113

Closed
aminophen opened this issue May 13, 2021 · 7 comments
Closed

[(u)pTeX] 禁則テーブルのハッシュ検索バグ #113

aminophen opened this issue May 13, 2021 · 7 comments
Labels

Comments

@aminophen
Copy link
Member

https://oku.edu.mie-u.ac.jp/tex/mod/forum/discuss.php?d=3113 を参照。

ptex-base.ch の get_kinsoku_pos 関数の assignment における挙動が変だと思います。

@aminophen aminophen added the bug label May 13, 2021
@aminophen
Copy link
Member Author

aminophen commented May 13, 2021

(原因はわかったのですがCコンパイラが入ったマシンを持ってきていないので,修正ができない…。)

今回のテストケースと,過去の #26, #57 のテストケースをもう一度走らせる必要がありますね。

@aminophen
Copy link
Member Author

aminophen commented May 15, 2021

とりあえず試してみているコード:

--- 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;

@aminophen
Copy link
Member Author

禁則テーブルのほかに 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;

@aminophen
Copy link
Member Author

上のコメントのパッチを適用した Win32 バイナリを置いてみます → ptex-new.zip

@aminophen
Copy link
Member Author

さらに \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

h-kitagawa added a commit to h-kitagawa/tex-jp-build that referenced this issue May 15, 2021
@h-kitagawa
Copy link
Member

とりあえず aminophen さんの 2 パッチを h-kitagawa@8039073 に入れておきました.

@aminophen
Copy link
Member Author

本 issue を Pull request にした #120 をマージしました。

  • 禁則テーブルの検索の修正 → r59700

なお,r59701 でバージョンを p3.9.1 にしています。

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

2 participants