Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

interp_send no longer converts SystemExit exceptions into Tcl::Error …

…exceptions, making it possible to implement ConsoleInterp#tcl_exit.

git-svn-id: svn://rubyforge.org/var/svn/tcl/trunk@14 017b7ecb-b1d0-4998-98d6-e9014aaf4887
  • Loading branch information...
commit 45f1372d6db625ed1851cbfd86214eaaa33348d7 1 parent 60c13cd
@sstephenson sstephenson authored
Showing with 27 additions and 3 deletions.
  1. +0 −2  TODO
  2. +5 −0 script/console
  3. +11 −1 src/tcl.c
  4. +11 −0 test/interp_receive_test.rb
View
2  TODO
@@ -1,4 +1,2 @@
* Tcl::Interp#to_tcl should account for interpreter aliases (see http://wiki.tcl.tk/8766) and namespaces.
-* Implement ConsoleInterp#exit.
-
View
5 script/console
@@ -6,11 +6,16 @@ class ConsoleInterp < Tcl::Interp
def initialize
super
expose :ruby_eval
+ expose :exit
end
def tcl_ruby_eval(script)
Kernel.eval(script)
end
+
+ def tcl_exit(code = 0)
+ exit(code.to_i)
+ end
end
filename = ARGV.shift || File.join(File.dirname(__FILE__), *%w".. .state.dat")
View
12 src/tcl.c
@@ -3,6 +3,7 @@
typedef struct {
Tcl_Interp *interp;
+ VALUE exit_exception;
} tcl_interp_struct;
static VALUE rb_value_to_s(VALUE value) {
@@ -38,6 +39,10 @@ static VALUE rb_tcl_interp_send_rescue(VALUE args, VALUE error_info) {
char *tcl_result = strdup(RSTRING(rb_value_to_s(error_info))->ptr);
Tcl_SetResult(tcl_interp->interp, tcl_result, (Tcl_FreeProc *)free);
+ if (rb_obj_is_kind_of(error_info, rb_eSystemExit)) {
+ tcl_interp->exit_exception = error_info;
+ }
+
return Qfalse;
}
@@ -67,6 +72,7 @@ static VALUE rb_tcl_interp_allocate(VALUE klass) {
VALUE obj = Data_Make_Struct(klass, tcl_interp_struct, NULL, rb_tcl_interp_destroy, tcl_interp);
tcl_interp->interp = Tcl_CreateInterp();
+ tcl_interp->exit_exception = Qnil;
Tcl_Init(tcl_interp->interp);
Tcl_Preserve(tcl_interp->interp);
@@ -130,7 +136,11 @@ static VALUE rb_tcl_interp_eval(VALUE self, VALUE script) {
case TCL_OK:
return rb_tainted_str_new2(tcl_interp->interp->result);
case TCL_ERROR:
- rb_raise(error_class, "%s", tcl_interp->interp->result);
+ if (NIL_P(tcl_interp->exit_exception)) {
+ rb_raise(error_class, "%s", tcl_interp->interp->result);
+ } else {
+ rb_exit(NUM2INT(rb_iv_get(tcl_interp->exit_exception, "status")));
+ }
default:
return Qnil;
}
View
11 test/interp_receive_test.rb
@@ -39,6 +39,12 @@ def tcl_hello(who)
end
end
+class InterpWithExitMethod < Tcl::Interp
+ def tcl_exit
+ exit
+ end
+end
+
class InterpReceiveTest < Test::Unit::TestCase
def setup
@interp = InterpWithDefaultReceiveMethod.new
@@ -91,5 +97,10 @@ def test_interp_expose
assert_equal "hello, Sam", @interp.eval("interp_send hello Sam")
assert_equal "hello, Sam", @interp.eval("hello Sam")
end
+
+ def test_interp_send_does_not_convert_system_exit_into_tcl_error
+ @interp = InterpWithExitMethod.new
+ assert_raises(SystemExit) { @interp.eval("interp_send exit") }
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.