[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[FDclone-users:00943] Re: ツリーで移動中にSEGV
- Subject: [FDclone-users:00943] Re: ツリーで移動中にSEGV
- From: Takashi SHIRAI <shirai@unixusers.net>
- Date: Fri, 09 Mar 2012 18:02:45 +0900
しらいです。
In Message-Id <20120229115318.1AC5887C001@yuka.unixusers.net>
Takashi SHIRAI <shirai@unixusers.net>writes:
> しらいです。
> 時間が掛かりそうなので Ack だけ返しておきます。FDclone の
> source code 見るのは一年ぶりくらいですか。
お待たせしましたがようやく直すことが出来ました。
> 出来れば本家の挙動に合わせて実装したいんですが、MS-DOS の
> 稼働環境が既に...。
patch は巻末に添付するとして、結局この本家の挙動に関して先
に解説しておきます。
頑張って MS-DOS 環境を用意して本家の挙動を紐解き、それに合
わせた仕様にしましたので、今回の bug fix に留まらない修正に
なっています。
本家の実装では、tree 行数が画面行数以内の場合には PageUp
も PageDown も無視されます。なので、これを踏襲するには tree
行数を知っておく必要があります。
FDclone では本家の実装と異なり、directory 探索時間を省くた
めに directory の折畳みを行なった tree 表記を採用しています。
つまりこの折畳みを展開しないと行数は判りません。
下位 directory を折畳んだ「>」付の directory に関しては、
元々 cursor 移動では展開されない仕様なので、PageUp/PageDown
でもそのままにしておきます。
問題は「その他」としてまとめられた「...」表記の directory
です。こちらはその位置に cursor を持っていくことで展開される
ので PageUp/PageDown でも対応が必要です。
ここで二つの実装が考えられます。一つは展開前に行数のみ調べ
て PageUp/PageDown の有効性を確認する方法で、もう一つは実際
に展開してしまってから行数を調べる方法です。
前者の場合、無効だった場合にはキー押下の前後で状況が何も変
わらないので、本家の挙動に忠実だと言えますが、折畳まれたまま
の状態では何故無効なのか利用者に伝わりにくいと思います。
後者の場合、無効だった場合には scroll はしないのに折畳み部
分の展開のみ遂行されるという気持ち悪さは残りますが、展開して
なお行数不足であることが利用者に伝わると思います。
どちらの実装も試してみたのですが、前者は存外に多くのコード
を必要とする割には、特にメリットと呼べる程の優位性が無く、無
駄なことをしているだけのように感じました。
ということで添付の patch では後者の実装を採用しています。
もし異論のある方がいるようでしたら再考しますので、release ま
でに意見を下さい。
尚 release 時期に関してですが、一年以上も溜め込んでいただ
けに他にも幾つか未発表の bug fix を含んでいます。そのため、
platform 別の検証に幾分時間がかかると思います。
折角環境を用意したので MS-DOS 版でもじっくりと検証を行ない
たいところですが、これがまた遅くて往生しております。VM 上に
しかない MINIX も結構な遅さです。
今月中には release 出来ればと思っていますが、余り期待せず
に待って頂けると幸いです。それまでは取り敢えずこの patch で
凌いで下さるようお願いします。
---- Cut Here ----
diff -ur ../old/FD-3.00j/tree.c ./tree.c
--- ../old/FD-3.00j/tree.c Sat Sep 25 00:00:00 2010
+++ ./tree.c Fri Mar 9 17:24:57 2012
@@ -36,6 +36,7 @@
static int NEAR treeup __P_((VOID_A));
static int NEAR treedown __P_((VOID_A));
static int NEAR freetree __P_((treelist *, int));
+static int NEAR bottomtree __P_((VOID_A));
static VOID NEAR _tree_search __P_((VOID_A));
static int NEAR _tree_input __P_((VOID_A));
static char *NEAR _tree __P_((VOID_A));
@@ -556,6 +557,24 @@
return(n);
}
+static int NEAR bottomtree(VOID_A)
+{
+ int min, oy, otop;
+
+ min = filetop(win);
+ oy = tr_line;
+ otop = tr_top;
+ while (tr_line < min + FILEPERROW - 2) if (treedown() < 0) break;
+ if (tr_line >= tr_bottom - 1 && tr_top >= min + 1) {
+ tr_line = oy;
+ tr_top = otop;
+ searchtree();
+ return(-1);
+ }
+
+ return(0);
+}
+
static VOID NEAR _tree_search(VOID_A)
{
int oy, otop;
@@ -595,23 +614,20 @@
treedown();
break;
case K_PPAGE:
+ if (bottomtree() < 0) break;
half = (FILEPERROW - 1) / 2;
- tmp = min + half + 1 - tr_line;
+ tmp = min + half + 1;
if (tr_top + half > min + 1) half = min - tr_top + 1;
if (half > 0) tr_top += half;
- for (;tmp > 0; tmp--) if (treedown() < 0) break;
- tr_line += tmp;
+ tr_line = tmp;
searchtree();
break;
case K_NPAGE:
+ if (bottomtree() < 0) break;
half = (FILEPERROW - 1) / 2;
- tmp = half + (min + half + 1) - tr_line;
- while (tmp-- > 0) if (treedown() < 0) break;
- tmp = tr_line - (min + half + 1);
- tr_line = min + half + 1;
- if (tr_bottom - tmp < min + FILEPERROW - 1)
- tmp = tr_bottom - min + FILEPERROW + 1;
- tr_top -= tmp;
+ tmp = min + half + 1;
+ while (half-- > 0) if (treedown() < 0) break;
+ tr_line = tmp;
searchtree();
break;
case K_BEG:
@@ -676,6 +692,7 @@
case K_BS:
do {
if (treeup() < 0) break;
+ if (!tr_cur || !(tr_cur -> sub)) break;
} while (&(tr_cur -> sub[tr_no]) != old);
break;
case 'l':
---- Cut Here ----
しらい たかし