[ruby-list:40626] Re: 安定版より安定しているバージョンでのTkでエラー
From:
Hidetoshi NAGAI <nagai@...>
Date:
2005-02-16 08:25:11 UTC
List:
ruby-list #40626
永井@知能.九工大です.
From: "Nobuyasu Hoshino" <n-hoshino@oose.co.jp>
Subject: [ruby-list:40625] Re: 安定版より安定しているバージョンでのTkでエラー
Date: Wed, 16 Feb 2005 14:59:21 +0900
Message-ID: <000c01c513ea$215ac900$3201a8c0@pc10>
> > (2) Ruby/Tk だけの問題であれば,ext/tk, ext/tcltklib 以下を
> > 12/25 版のものと置き換えて試す.
> やってみましたがダメでした。
> 逆に 12/25版の ruby に、2/10版の上記を置き換えたのはOKでした。
報告をありがとうございます.確認しました.
原因は 2/8 に commit された st.c の st_foreach の変更に
tkutil.c の一部が追随できていなかったためでした.
この修正に加え,SJIS 文字列の配列を Tcl/Tk のリスト文字列に
自動変換させた場合に一部の SJIS 文字を含んでいると適切に
変換されない (特殊文字を含んだリスト要素として { } で囲まれてしまう)
という問題の修正も含めて commit しておきました.
# ちょっとした問題 (バグとは言えないレベルも含みます) や希望も
# 気軽に報告して頂けると本当に助かります.
# 隅々までもチェックしきれている訳ではないので,
# 報告さえあれば簡単に直せるバグがそのままになっているケースも
# ありますので.
差分は以下の通りです.お試しください.
Index: tkutil.c
===================================================================
RCS file: /var/cvs/src/ruby/ext/tk/Attic/tkutil.c,v
retrieving revision 1.4.2.15
diff -u -r1.4.2.15 tkutil.c
--- tkutil.c 25 Jan 2005 05:08:23 -0000 1.4.2.15
+++ tkutil.c 16 Feb 2005 07:59:53 -0000
@@ -8,7 +8,7 @@
************************************************/
-#define TKUTIL_RELEASE_DATE "2005-01-25"
+#define TKUTIL_RELEASE_DATE "2005-02-16"
#include "ruby.h"
#include "rubysig.h"
@@ -199,24 +199,12 @@
return tk_fromUTF8(1, argv, self);
}
-
-static void
-hash_check(err)
- int err;
-{
- if (err) {
- rb_raise(rb_eRuntimeError, "hash modified");
- }
-}
-
static int
-to_strkey(key, value, hash, err)
+to_strkey(key, value, hash)
VALUE key;
VALUE value;
VALUE hash;
- int err;
{
- hash_check(err);
if (key == Qundef) return ST_CONTINUE;
rb_hash_aset(hash, rb_funcall(key, ID_to_s, 0, 0), value);
return ST_CHECK;
@@ -231,19 +219,23 @@
if NIL_P(keys) return new_keys;
keys = rb_convert_type(keys, T_HASH, "Hash", "to_hash");
- st_foreach(RHASH(keys)->tbl, to_strkey, new_keys);
+ if (st_foreach(RHASH(keys)->tbl, to_strkey, new_keys)) {
+ rb_raise(rb_eRuntimeError, "hash modified during iteration");
+ }
return new_keys;
}
static VALUE get_eval_string_core _((VALUE, VALUE, VALUE));
-static VALUE ary2list _((VALUE, VALUE));
-static VALUE ary2list2 _((VALUE, VALUE));
+static VALUE ary2list _((VALUE, VALUE, VALUE));
+static VALUE ary2list2 _((VALUE, VALUE, VALUE));
static VALUE hash2list _((VALUE, VALUE));
+static VALUE hash2list_enc _((VALUE, VALUE));
static VALUE hash2kv _((VALUE, VALUE, VALUE));
static VALUE
-ary2list(ary, self)
+ary2list(ary, enc_flag, self)
VALUE ary;
+ VALUE enc_flag;
VALUE self;
{
int idx, idx2, size, size2;
@@ -266,29 +258,36 @@
val = RARRAY(ary)->ptr[idx];
switch(TYPE(val)) {
case T_ARRAY:
- RARRAY(dst)->ptr[RARRAY(dst)->len++] = ary2list(val, self);
+ RARRAY(dst)->ptr[RARRAY(dst)->len++]
+ = ary2list(val, enc_flag, self);
break;
case T_HASH:
/* RARRAY(dst)->ptr[RARRAY(dst)->len++] = hash2list(val, self); */
- val = hash2kv(val, Qnil, self);
+ val = hash2kv(val, enc_flag, self);
size2 = RARRAY(val)->len;
for(idx2 = 0; idx2 < size2; idx2++) {
val2 = RARRAY(val)->ptr[idx2];
switch(TYPE(val2)) {
case T_ARRAY:
RARRAY(dst)->ptr[RARRAY(dst)->len++]
- = ary2list(val2, self);
+ = ary2list(val2, enc_flag, self);
break;
case T_HASH:
- RARRAY(dst)->ptr[RARRAY(dst)->len++]
- = hash2list(val2, self);
+ if (RTEST(enc_flag)) {
+ RARRAY(dst)->ptr[RARRAY(dst)->len++]
+ = hash2list_enc(val2, self);
+ } else {
+ RARRAY(dst)->ptr[RARRAY(dst)->len++]
+ = hash2list(val2, self);
+ }
+ break;
default:
if (val2 != TK_None) {
RARRAY(dst)->ptr[RARRAY(dst)->len++]
- = get_eval_string_core(val2, Qnil, self);
+ = get_eval_string_core(val2, enc_flag, self);
}
}
}
@@ -297,7 +296,7 @@
default:
if (val != TK_None) {
RARRAY(dst)->ptr[RARRAY(dst)->len++]
- = get_eval_string_core(val, Qnil, self);
+ = get_eval_string_core(val, enc_flag, self);
}
}
}
@@ -305,8 +304,9 @@
}
static VALUE
-ary2list2(ary, self)
+ary2list2(ary, enc_flag, self)
VALUE ary;
+ VALUE enc_flag;
VALUE self;
{
int idx, size;
@@ -320,17 +320,23 @@
val = RARRAY(ary)->ptr[idx];
switch(TYPE(val)) {
case T_ARRAY:
- RARRAY(dst)->ptr[RARRAY(dst)->len++] = ary2list(val, self);
+ RARRAY(dst)->ptr[RARRAY(dst)->len++]
+ = ary2list(val, enc_flag, self);
break;
case T_HASH:
- RARRAY(dst)->ptr[RARRAY(dst)->len++] = hash2list(val, self);
+ if (RTEST(enc_flag)) {
+ RARRAY(dst)->ptr[RARRAY(dst)->len++] = hash2list(val, self);
+ } else {
+ RARRAY(dst)->ptr[RARRAY(dst)->len++]
+ = hash2list_enc(val, self);
+ }
break;
default:
if (val != TK_None) {
RARRAY(dst)->ptr[RARRAY(dst)->len++]
- = get_eval_string_core(val, Qnil, self);
+ = get_eval_string_core(val, enc_flag, self);
}
}
}
@@ -449,15 +455,13 @@
}
static int
-push_kv(key, val, args, err)
+push_kv(key, val, args)
VALUE key;
VALUE val;
VALUE args;
- int err;
{
volatile VALUE ary;
- hash_check(err);
ary = RARRAY(args)->ptr[0];
if (key == Qundef) return ST_CONTINUE;
@@ -489,7 +493,9 @@
RARRAY(args)->ptr[0] = dst;
RARRAY(args)->ptr[1] = self;
RARRAY(args)->len = 2;
- st_foreach(RHASH(hash)->tbl, push_kv, args);
+ if (st_foreach(RHASH(hash)->tbl, push_kv, args)) {
+ rb_raise(rb_eRuntimeError, "hash modified during iteration");
+ }
if (NIL_P(ary)) {
return dst;
@@ -499,15 +505,13 @@
}
static int
-push_kv_enc(key, val, args, err)
+push_kv_enc(key, val, args)
VALUE key;
VALUE val;
VALUE args;
- int err;
{
volatile VALUE ary;
- hash_check(err);
ary = RARRAY(args)->ptr[0];
if (key == Qundef) return ST_CONTINUE;
@@ -542,7 +546,9 @@
RARRAY(args)->ptr[0] = dst;
RARRAY(args)->ptr[1] = self;
RARRAY(args)->len = 2;
- st_foreach(RHASH(hash)->tbl, push_kv_enc, args);
+ if (st_foreach(RHASH(hash)->tbl, push_kv_enc, args)) {
+ rb_raise(rb_eRuntimeError, "hash modified during iteration");
+ }
if (NIL_P(ary)) {
return dst;
@@ -556,7 +562,7 @@
VALUE hash;
VALUE self;
{
- return ary2list2(hash2kv(hash, Qnil, self), self);
+ return ary2list2(hash2kv(hash, Qnil, self), Qfalse, self);
}
@@ -565,7 +571,7 @@
VALUE hash;
VALUE self;
{
- return ary2list2(hash2kv_enc(hash, Qnil, self), self);
+ return ary2list2(hash2kv_enc(hash, Qnil, self), Qfalse, self);
}
static VALUE
@@ -669,11 +675,7 @@
}
case T_ARRAY:
- if (RTEST(enc_flag)) {
- return fromDefaultEnc_toUTF8(ary2list(obj, self), self);
- } else {
- return ary2list(obj, self);
- }
+ return ary2list(obj, enc_flag, self);
case T_FALSE:
return rb_str_new2("0");
--
永井 秀利 (九工大 知能情報)
nagai@ai.kyutech.ac.jp