From 3124427ccbf02a5bd20f169ad6a328286e05c262 Mon Sep 17 00:00:00 2001 From: nagai Date: Wed, 2 Mar 2005 07:06:52 +0000 Subject: * ext/tk/tcltklib.c: enforce thread-check and exception-handling to avoid SEGV trouble. * ext/tk/tkutil/tkutil.c; fix a bug on converting a SJIS string array to a Tcl's list string. * ext/tk/tcltklib.c: wrap Tcl's original "namespace" command to protect from namespace crash. * ext/tk/lib/multi-tk.rb: enforce exception-handling. * ext/tk/lib/multi-tk.rb: catch IRB_EXIT to work on irb. * ext/tk/lib/tk.rb: ditto. * ext/tk/tcltklib.c: add TclTkLib.mainloop_thread? * ext/tk/lib/multi-tk.rb: (bug fix) callback returns a value. * ext/tk/lib/tk/canvas.rb (delete): bug fix when multiple arguments. * ext/tk/lib/clock.rb: fix 'no method error'. * ext/tk/lib/clock.rb (self.clicks): accept a Symbol argument. * ext/tk/lib/variable.rb: be able to set default_value_type; :numeric, :bool, :string, :symbol, :list, :numlist or nil (default; same to :string). If set a type, TkVariable#value returns a value of the type. * ext/tk/lib/tkextlib/tclx/tclx.rb: add Tk::TclX.signal to warn the risk of using TclX extension's 'signal' command. * ext/tk/sample/irbtk.rb: irb with Ruby/Tk. * ext/tk/sample/demos-*/anilabel.rb: bug fix on 'show code' * ext/tk/sample/demos-*/aniwave.rb: new Ruby/Tk animation demo. * ext/tk/sample/demos-*/pendulum.rb: ditto. * ext/tk/sample/demos-*/goldberg.rb: ditto. * ext/tk/sample/demos-*/widget: add entries of animation demos. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8046 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/tk/tkutil/tkutil.c | 98 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 75 insertions(+), 23 deletions(-) (limited to 'ext/tk/tkutil') diff --git a/ext/tk/tkutil/tkutil.c b/ext/tk/tkutil/tkutil.c index d88f7b9a72..bedf12642a 100644 --- a/ext/tk/tkutil/tkutil.c +++ b/ext/tk/tkutil/tkutil.c @@ -8,12 +8,20 @@ ************************************************/ -#define TKUTIL_RELEASE_DATE "2005-01-25" +#define TKUTIL_RELEASE_DATE "2005-03-02" #include "ruby.h" #include "rubysig.h" #include "st.h" +/* check ruby_version */ +#include "version.h" +#if RUBY_VERSION_MINOR == 9 +#define ST_FOREACH_PASS_ERR_ARG 1 /* Ruby 1.9 */ +#else +#define ST_FOREACH_PASS_ERR_ARG 0 /* Ruby 1.8 (from 2005/02/08) */ +#endif + static VALUE cMethod; static VALUE cTclTkLib; @@ -200,23 +208,35 @@ fromUTF8_toDefaultEnc(str, self) } +#if ST_FOREACH_PASS_ERR_ARG static void hash_check(err) int err; { if (err) { - rb_raise(rb_eRuntimeError, "hash modified"); + rb_raise(rb_eRuntimeError, "hash modified during iteration"); } } +#endif +#if ST_FOREACH_PASS_ERR_ARG static int to_strkey(key, value, hash, err) VALUE key; VALUE value; VALUE hash; int err; +#else +static int +to_strkey(key, value, hash) + VALUE key; + VALUE value; + VALUE hash; +#endif { +#if ST_FOREACH_PASS_ERR_ARG hash_check(err); +#endif if (key == Qundef) return ST_CONTINUE; rb_hash_aset(hash, rb_funcall(key, ID_to_s, 0, 0), value); return ST_CHECK; @@ -236,14 +256,16 @@ tk_symbolkey2str(self, 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 +288,36 @@ ary2list(ary, self) 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 +326,7 @@ ary2list(ary, self) 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 +334,9 @@ ary2list(ary, self) } static VALUE -ary2list2(ary, self) +ary2list2(ary, enc_flag, self) VALUE ary; + VALUE enc_flag; VALUE self; { int idx, size; @@ -320,17 +350,23 @@ ary2list2(ary, self) 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); } } } @@ -448,16 +484,26 @@ assoc2kv_enc(assoc, ary, self) } } +#if ST_FOREACH_PASS_ERR_ARG static int push_kv(key, val, args, err) VALUE key; VALUE val; VALUE args; int err; +#else +static int +push_kv(key, val, args) + VALUE key; + VALUE val; + VALUE args; +#endif { volatile VALUE ary; +#if ST_FOREACH_PASS_ERR_ARG hash_check(err); +#endif ary = RARRAY(args)->ptr[0]; if (key == Qundef) return ST_CONTINUE; @@ -498,16 +544,26 @@ hash2kv(hash, ary, self) } } +#if ST_FOREACH_PASS_ERR_ARG static int push_kv_enc(key, val, args, err) VALUE key; VALUE val; VALUE args; int err; +#else +static int +push_kv_enc(key, val, args) + VALUE key; + VALUE val; + VALUE args; +#endif { volatile VALUE ary; +#if ST_FOREACH_PASS_ERR_ARG hash_check(err); +#endif ary = RARRAY(args)->ptr[0]; if (key == Qundef) return ST_CONTINUE; @@ -556,7 +612,7 @@ hash2list(hash, self) VALUE hash; VALUE self; { - return ary2list2(hash2kv(hash, Qnil, self), self); + return ary2list2(hash2kv(hash, Qnil, self), Qfalse, self); } @@ -565,7 +621,7 @@ hash2list_enc(hash, self) 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 +725,7 @@ get_eval_string_core(obj, enc_flag, self) } 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"); -- cgit v1.2.3