From 4158a73ee47321de856b8bce5668b07a824d3374 Mon Sep 17 00:00:00 2001 From: nagai Date: Mon, 28 Jul 2003 06:10:13 +0000 Subject: [PATCH] tcltklib.c : *bug fix multi-tk.rb : *bug fix *add methods depend on Tcl's 'interp' command *suppot to control safe-level of each interpreter git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/tcltklib/tcltklib.c | 7 +- ext/tk/lib/multi-tk.rb | 325 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 318 insertions(+), 14 deletions(-) diff --git a/ext/tcltklib/tcltklib.c b/ext/tcltklib/tcltklib.c index bf258f6d9b..cad67babe0 100644 --- a/ext/tcltklib/tcltklib.c +++ b/ext/tcltklib/tcltklib.c @@ -217,7 +217,7 @@ rb_evloop_abort_no_cmd_set(self, val) { rb_secure(4); event_loop_abort_no_cmd = (val == Qtrue)? 1: 0; - return rb_event_loop_abort_no_cmd(); + return rb_evloop_abort_no_cmd(); } VALUE @@ -710,8 +710,7 @@ ip_create_slave(argc, argv, self) /* create slave-ip */ if ((slave->ip = Tcl_CreateSlave(master->ip, StringValuePtr(name), safe)) == NULL) { - rb_ip_raise(self, rb_eRuntimeError, - "fail to create the new slave interpreter"); + rb_raise(rb_eRuntimeError, "fail to create the new slave interpreter"); } Tcl_Preserve((ClientData)slave->ip); slave->return_value = 0; @@ -727,7 +726,7 @@ ip_make_safe(self) struct tcltkip *ptr = get_ip(self); if (Tcl_MakeSafe(ptr->ip) == TCL_ERROR) { - rb_ip_raise(self, rb_eRuntimeError, "%s", ptr->ip->result); + rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); } return self; diff --git a/ext/tk/lib/multi-tk.rb b/ext/tk/lib/multi-tk.rb index 808370e05f..59e7e1d9ce 100644 --- a/ext/tk/lib/multi-tk.rb +++ b/ext/tk/lib/multi-tk.rb @@ -82,19 +82,43 @@ class MultiTkIp return thread end + ###################################### + + def set_safe_level(safe) + @cmd_queue.enq([@system, 'set_safe_level', safe]) + self + end + def self.set_safe_level(safe) + __getip.set_safe_level(safe) + self + end + def _create_receiver_and_watchdog() # command-procedures receiver receiver = Thread.new{ loop do thread, cmd, *args = @cmd_queue.deq - begin - ret = cmd.call(*args) - rescue Exception => e - # raise exception - _check_and_return(thread, e) + if thread == @system + case cmd + when 'set_safe_level' + begin + $SAFE = args[0] + rescue Exception + nil + end + else + # ignore + end else - # no exception - _check_and_return(thread, MultiTkIp_OK.new(ret)) + begin + ret = cmd.call(*args) + rescue Exception => e + # raise exception + _check_and_return(thread, e) + else + # no exception + _check_and_return(thread, MultiTkIp_OK.new(ret)) + end end end } @@ -155,6 +179,8 @@ class MultiTkIp @interp = TclTkIp.new(name, _keys2opts(keys)) @ip_name = nil + @system = Object.new + @threadgroup = Thread.current.group @cmd_queue = Queue.new @@ -411,6 +437,8 @@ class MultiTkIp }.freeze end + @system = Object.new + @threadgroup = ThreadGroup.new @cmd_queue = Queue.new @@ -494,18 +522,47 @@ class MultiTkIp true end end + def self.master? + __getip.master? + end def slave? not master? end + def self.slave? + end def alive? - return false unless @cmd_receiver.alive? - return false if @interp.deleted? + begin + return false unless @cmd_receiver.alive? + return false if @interp.deleted? + return false if @interp._invoke('interp', 'exists', '') == '0' + rescue Exception + return false + end + true + end + def self.alive? + __getip.alive? end def path - @ip_name + @ip_name || '' + end + def self.path + __getip.path + end + def ip_name + @ip_name || '' + end + def self.ip_name + __getip.ip_name + end + def to_eval + @ip_name || '' + end + def self.to_eval + __getip.to_eval end def slaves(all = false) @@ -519,6 +576,9 @@ class MultiTkIp end }.compact! end + def self.slaves(all = false) + __getip.slaves(all) + end end @@ -783,6 +843,251 @@ class MultiTkIp end +# interp command support +class MultiTkIp + def _lst2ary(str) + return [] if str == "" + idx = str.index('{') + while idx and idx > 0 and str[idx-1] == ?\\ + idx = str.index('{', idx+1) + end + return str.split unless idx + + list = str[0,idx].split + str = str[idx+1..-1] + i = -1 + brace = 1 + str.each_byte {|c| + i += 1 + brace += 1 if c == ?{ + brace -= 1 if c == ?} + break if brace == 0 + } + if i == 0 + list.push '' + elsif str[0, i] == ' ' + list.push ' ' + else + list.push str[0..i-1] + end + list += tk_split_simplelist(str[i+1..-1]) + list + end + private :_lst2ary + + def _slavearg(slave) + if slave.kind_of?(MultiTkIp) + slave.path + elsif slave.kind_of?(String) + slave + else + cmd_name.to_s + end + end + private :_slavearg + + def alias_info(slave, cmd_name) + _lst2ary(@interp._invoke('interp', 'alias', _slavearg(slave), cmd_name)) + end + def self.alias_info(slave, cmd_name) + __getip.alias_info(slave, cmd_name) + end + + def alias_delete(slave, cmd_name) + @interp._invoke('interp', 'alias', _slavearg(slave), cmd_name, '') + self + end + def self.alias_delete(slave, cmd_name) + __getip.alias_delete(slave, cmd_name) + self + end + + def def_alias(slave, new_cmd, org_cmd, *args) + ret = @interp._invoke('interp', 'alias', _slavearg(slave), new_cmd, + '', org_cmd, *args) + (ret == new_cmd)? self: nil + end + def self.def_alias(slave, new_cmd, org_cmd, *args) + ret = __getip.def_alias(slave, new_cmd, org_cmd, *args) + (ret == new_cmd)? self: nil + end + + def aliases(slave = '') + _lst2ary(@interp._invoke('interp', 'aliases', _slavearg(slave))) + end + def self.aliases(slave = '') + __getip.aliases(slave) + end + + def delete_slaves(*args) + slaves = args.collect{|s| _slavearg(s)} + @interp._invoke('interp', 'delete', *slaves) if slaves.size > 0 + self + end + def self.delete_slaves(*args) + __getip.delete_slaves(*args) + self + end + + def exist?(slave = '') + ret = @interp._invoke('interp', 'exists', _slavearg(slave)) + (ret == '1')? true: false + end + def self.exist?(slave = '') + __getip.exist?(slave) + end + + def delete_cmd(slave, cmd) + slave_invoke = @interp._invoke('list', 'rename', cmd, '') + @interp._invoke('interp', 'eval', _slavearg(slave), slave_invoke) + self + end + def self.delete_cmd(slave, cmd) + __getip.delete_cmd(slave, cmd) + self + end + + def expose_cmd(slave, cmd, aliasname = nil) + if aliasname + @interp._invoke('interp', 'expose', _slavearg(slave), cmd, aliasname) + else + @interp._invoke('interp', 'expose', _slavearg(slave), cmd) + end + self + end + def self.expose_cmd(slave, cmd, aliasname = nil) + __getip.expose_cmd(slave, cmd, aliasname) + self + end + + def hide_cmd(slave, cmd, aliasname = nil) + if aliasname + @interp._invoke('interp', 'hide', _slavearg(slave), cmd, aliasname) + else + @interp._invoke('interp', 'hide', _slavearg(slave), cmd) + end + self + end + def self.hide_cmd(slave, cmd, aliasname = nil) + __getip.hide_cmd(slave, cmd, aliasname) + self + end + + def hidden_cmds(slave = '') + _lst2ary(@interp._invoke('interp', 'hidden', _slavearg(slave))) + end + def self.hidden_cmds(slave = '') + __getip.hidden_cmds(slave) + end + + def invoke_hidden(slave, cmd, *args) + @interp._invoke('interp', 'invokehidden', _slavearg(slave), cmd, *args) + end + def self.invoke_hidden(slave, cmd, *args) + __getip.invoke_hidden(slave, cmd, *args) + end + + def invoke_hidden_on_global(slave, cmd, *args) + @interp._invoke('interp', 'invokehidden', _slavearg(slave), + '-global', cmd, *args) + end + def self.invoke_hidden_on_global(slave, cmd, *args) + __getip.invoke_hidden_on_global(slave, cmd, *args) + end + + def mark_trusted(slave = '') + @interp._invoke('interp', 'marktrusted', _slavearg(slave)) + self + end + def self.mark_trusted(slave = '') + __getip.mark_trusted(slave) + self + end + + def alias_target(aliascmd, slave = '') + @interp._invoke('interp', 'target', _slavearg(slave), aliascmd) + end + def self.alias_target(aliascmd, slave = '') + __getip.alias_target(aliascmd, slave) + end + + def share_stdin(dist, src = '') + @interp._invoke('interp', 'share', src, 'stdin', dist) + self + end + def self.share_stdin(dist, src = '') + __getip.share_stdin(dist, src) + self + end + + def share_stdout(dist, src = '') + @interp._invoke('interp', 'share', src, 'stdout', dist) + self + end + def self.share_stdout(dist, src = '') + __getip.share_stdout(dist, src) + self + end + + def share_stderr(dist, src = '') + @interp._invoke('interp', 'share', src, 'stderr', dist) + self + end + def self.share_stderr(dist, src = '') + __getip.share_stderr(dist, src) + self + end + + def transfer_stdin(dist, src = '') + @interp._invoke('interp', 'transfer', src, 'stdin', dist) + self + end + def self.transfer_stdin(dist, src = '') + __getip.transfer_stdin(dist, src) + self + end + + def transfer_stdout(dist, src = '') + @interp._invoke('interp', 'transfer', src, 'stdout', dist) + self + end + def self.transfer_stdout(dist, src = '') + __getip.transfer_stdout(dist, src) + self + end + + def transfer_stderr(dist, src = '') + @interp._invoke('interp', 'transfer', src, 'stderr', dist) + self + end + def self.transfer_stderr(dist, src = '') + __getip.transfer_stderr(dist, src) + self + end + + def share_stdio(dist, src = '') + @interp._invoke('interp', 'share', src, 'stdin', dist) + @interp._invoke('interp', 'share', src, 'stdout', dist) + @interp._invoke('interp', 'share', src, 'stderr', dist) + self + end + def self.share_stdio(dist, src = '') + __getip.share_stdio(dist, src) + self + end + + def transfer_stdio(dist, src = '') + @interp._invoke('interp', 'transfer', src, 'stdin', dist) + @interp._invoke('interp', 'transfer', src, 'stdout', dist) + @interp._invoke('interp', 'transfer', src, 'stderr', dist) + self + end + def self.transfer_stdio(dist, src = '') + __getip.transfer_stdio(dist, src) + self + end +end + # end of MultiTkIp definition MultiTkIp.freeze # defend against modification