summaryrefslogtreecommitdiffstats
path: root/ext/tk/tkutil.c
diff options
context:
space:
mode:
authornagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-03-02 07:08:18 +0000
committernagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-03-02 07:08:18 +0000
commit629c16f9cd8069a8b35da747ecc3c7649a6dea65 (patch)
tree202fdc4daf958bdad32c9ea2e2cc48b40a782304 /ext/tk/tkutil.c
parentefe850680a53fcaa0b58dd2d0e0399cbaf870805 (diff)
downloadruby-629c16f9cd8069a8b35da747ecc3c7649a6dea65.tar.gz
ruby-629c16f9cd8069a8b35da747ecc3c7649a6dea65.tar.xz
ruby-629c16f9cd8069a8b35da747ecc3c7649a6dea65.zip
* ext/tcltklib/tcltklib.c: enforce thread-check and exception-handling to
avoid SEGV trouble. [KNOWN BUG] When supports pthread and running multiple Tk interpreters, an interrupt signal causes SEGV frequently. That may be a trouble of Ruby's signal handler. * 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: http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8@8048 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/tk/tkutil.c')
-rw-r--r--ext/tk/tkutil.c70
1 files changed, 60 insertions, 10 deletions
diff --git a/ext/tk/tkutil.c b/ext/tk/tkutil.c
index 221432bb7..bedf12642 100644
--- a/ext/tk/tkutil.c
+++ b/ext/tk/tkutil.c
@@ -8,12 +8,20 @@
************************************************/
-#define TKUTIL_RELEASE_DATE "2005-02-16"
+#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;
@@ -199,12 +207,36 @@ fromUTF8_toDefaultEnc(str, self)
return tk_fromUTF8(1, argv, self);
}
+
+#if ST_FOREACH_PASS_ERR_ARG
+static void
+hash_check(err)
+ int err;
+{
+ if (err) {
+ 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;
@@ -219,9 +251,7 @@ tk_symbolkey2str(self, keys)
if NIL_P(keys) return new_keys;
keys = rb_convert_type(keys, T_HASH, "Hash", "to_hash");
- if (st_foreach(RHASH(keys)->tbl, to_strkey, new_keys)) {
- rb_raise(rb_eRuntimeError, "hash modified during iteration");
- }
+ st_foreach(RHASH(keys)->tbl, to_strkey, new_keys);
return new_keys;
}
@@ -454,14 +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;
@@ -493,9 +535,7 @@ hash2kv(hash, ary, self)
RARRAY(args)->ptr[0] = dst;
RARRAY(args)->ptr[1] = self;
RARRAY(args)->len = 2;
- if (st_foreach(RHASH(hash)->tbl, push_kv, args)) {
- rb_raise(rb_eRuntimeError, "hash modified during iteration");
- }
+ st_foreach(RHASH(hash)->tbl, push_kv, args);
if (NIL_P(ary)) {
return dst;
@@ -504,14 +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;
@@ -546,9 +598,7 @@ hash2kv_enc(hash, ary, self)
RARRAY(args)->ptr[0] = dst;
RARRAY(args)->ptr[1] = self;
RARRAY(args)->len = 2;
- if (st_foreach(RHASH(hash)->tbl, push_kv_enc, args)) {
- rb_raise(rb_eRuntimeError, "hash modified during iteration");
- }
+ st_foreach(RHASH(hash)->tbl, push_kv_enc, args);
if (NIL_P(ary)) {
return dst;