[#39464] Re [ruby-dev:23297] 大文字・小文字の区別がDOSISHかどうかで変わる、パス名マッチ関数の提案 — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>

山本です。

25 messages 2004/04/01
[#39608] Re: Re [ruby-dev:23297] 大文字・小文字の区別がDOSISHかどうかで変わる、パス名マッチ関数の提案 — pegacorn@... 2004/05/02

遅い反応&File.fnmatchは使った事ない&ruby-devの方では

[#39609] Re: Re [ruby-dev:23297] 大文字・小文字の区別がDOSISHかどうかで変わる、パス名マッチ関数の提案 — pegacorn@... 2004/05/02

File.fnmatch(と Dir.glob)をちょっと使ってみたのですが、

[#39610] Re: Re [ruby-dev:23297] 大文字・小文字の区別がDOSISHかどうかで変わる、パス名マッチ関数の提案 — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2004/05/02

山本です。

[#39611] Re: Re [ruby-dev:23297] 大文字・小文字の区別がDOSISHかどうかで変わる、パス名マッチ関数の提案 — matz@... (Yukihiro Matsumoto) 2004/05/02

まつもと ゆきひろです

[#39613] Re: Re [ruby-dev:23297] 大文字・小文字の区別がDOSISHかどうかで変わる、パス名マッチ関数の提案 — pegacorn@... 2004/05/02

From: matz@ruby-lang.org (Yukihiro Matsumoto)

[#39616] Re: Re [ruby-dev:23297] 大文字・小文字の区別がDOSISHかどうかで変わる、パス名マッチ関数の提案 — matz@... (Yukihiro Matsumoto) 2004/05/02

まつもと ゆきひろです

[#39620] Re: Re [ruby-dev:23297] 大文字・小文字の区別がDOSISHかどうかで変わる、パス名マッチ関数の提案 — pegacorn@... 2004/05/03

From: matz@ruby-lang.org (Yukihiro Matsumoto)

[#39621] Re: Re [ruby-dev:23297] 大文字・小文字の区別がDOSISHかどうかで変わる、パス名マッチ関数の提案 — matz@... (Yukihiro Matsumoto) 2004/05/03

まつもと ゆきひろです

[#39622] Re: Re [ruby-dev:23297] 大文字・小文字の区別がDOSISHかどうかで変わる、パス名マッチ関数の提案 — pegacorn@... 2004/05/03

From: matz@ruby-lang.org (Yukihiro Matsumoto)

[ruby-list:39460] Re: trial version of Ruby/Tk

From: Hidetoshi NAGAI <nagai@...>
Date: 2004-04-01 04:09:56 UTC
List: ruby-list #39460
永井@知能.九工大です.

From: "Shirai,Kaoru" <shirai@korinkan.co.jp>
Subject: [ruby-list:39454] Re: trial version of Ruby/Tk
Date: Wed, 31 Mar 2004 21:19:50 +0900
Message-ID: <20040331.211944.884114422.nobody@localhost>
> tcltk20040323を Ruby-1.8.1(i686-linux) + Tk8.4.6 で試してみました。
> $ ruby -r tk -e 'exit'
> とすると、TERMシグナルを受けるまで固まってしまいます。ちなみに、exit! 
> やスクリプトの終端に達したときは正常に終了するのですが…?

報告をありがとうございます.
手元でさらに改修を加えたものでは固まらないように見えます.
お手数ですが tcltk20040323 版に添付パッチを適用したもので
試してみていただけませんか.

# もしかすると,Exerb で Tk が正常に終了しないというのと
# 同じ原因なのかもしれないですね.

バグ修正に加え,Tcl/Tk8.5a1 の新機能にまで対応させた (つもりの (^_^;) 
新しいものは近いうちに出します.
添付パッチはそれに含まれる予定のものとの差分です.

--- ../20040323/tcltklib/tcltklib.c	2004-03-23 18:06:03.000000000 +0900
+++ tcltklib.c	2004-04-01 12:59:24.000000000 +0900
@@ -101,6 +101,23 @@
     VALUE result;
     VALUE thread;
 };
+
+void 
+invoke_queue_mark(struct invoke_queue *q)
+{
+    rb_gc_mark(q->interp);
+    rb_gc_mark(q->result);
+    rb_gc_mark(q->thread);
+}
+
+void 
+eval_queue_mark(struct eval_queue *q)
+{
+    rb_gc_mark(q->interp);
+    rb_gc_mark(q->result);
+    rb_gc_mark(q->thread);
+}
+
  
 static VALUE eventloop_thread;
 static VALUE watchdog_thread;
@@ -458,7 +475,9 @@
 	    DUMP1("check Root Widget");
 	    if (check_root && Tk_GetNumMainWindows() == 0) {
 		run_timer_flag = 0;
-		rb_trap_exec();
+		if (!rb_prohibit_interrupt) {
+		  if (rb_trap_pending) rb_trap_exec();
+		}
 		return 1;
 	    }
 
@@ -467,23 +486,6 @@
 		loop_counter = 0;
 	    }
 
-#if 0
-	    if (run_timer_flag) {
-		/* 
-		DUMP1("timer interrupt");
-		run_timer_flag = 0;
-		DUMP1("call rb_trap_exec()");
-		rb_trap_exec();
-		*/
-		DUMP1("check Root Widget");
-		if (check_root && Tk_GetNumMainWindows() == 0) {
-		    run_timer_flag = 0;
-		    rb_trap_exec();
-		    return 1;
-		}
-	    }
-#endif
-
 	} else {
 	    int tick_counter;
 
@@ -505,31 +507,32 @@
 		    tick_counter++;
 		} else {
 		    tick_counter += no_event_tick;
-#if 0
-		    DUMP1("check Root Widget");
-		    if (check_root && Tk_GetNumMainWindows() == 0) {
-			return 1;
-		    }
-#endif
 		    rb_thread_wait_for(t);
 		}
 
+		if (watchdog_thread != 0 && eventloop_thread != current) {
+		    return 1;
+		}
+
 		DUMP1("check Root Widget");
 		if (check_root && Tk_GetNumMainWindows() == 0) {
 		    run_timer_flag = 0;
-		    rb_trap_exec();
+		    if (!rb_prohibit_interrupt) {
+		      if (rb_trap_pending) rb_trap_exec();
+		    }
 		    return 1;
 		}
 
+		DUMP1("trap check");
+		if (!rb_prohibit_interrupt) {
+		  if (rb_trap_pending) rb_trap_exec();
+		}
+
 		if (loop_counter++ > 30000) {
 		    /* fprintf(stderr, "loop_counter > 30000\n"); */
 		    loop_counter = 0;
 		}
 
-		if (watchdog_thread != 0 && eventloop_thread != current) {
-		    return 1;
-		}
-
 		if (run_timer_flag) {
 		    /*
 		    DUMP1("timer interrupt");
@@ -538,25 +541,11 @@
 		    break; /* switch to other thread */
 		}
 	    }
-
-#if 0
-	    DUMP1("check Root Widget");
-	    if (check_root && Tk_GetNumMainWindows() == 0) {
-		return 1;
-	    }
-#endif
 	}
 
-	/* rb_thread_schedule(); */
-	if (run_timer_flag) {
-	    run_timer_flag = 0;
-	    rb_trap_exec();
-	} else {
-            DUMP1("thread scheduling");
-	    if (is_ruby_native_thread()) {
-		rb_thread_schedule();
-	    }
-	}
+	DUMP1("trap check & thread scheduling");
+	CHECK_INTS;
+
     }
     return 1;
 }
@@ -866,7 +855,7 @@
 
     /* ruby command has 1 arg. */
     if (argc != 2) {
-	rb_raise(rb_eArgError, "wrong # of arguments (%d for 1)", argc);
+	rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
     }
 
     /* get C string from Tcl object */
@@ -907,7 +896,7 @@
     /* status check */
     if (arg.failed) {
         VALUE eclass;
-        /* volatile VALUE backtrace; */
+        volatile VALUE backtrace;
 
 	DUMP1("(rb_eval_string result) failed");
 
@@ -916,16 +905,18 @@
 	res = arg.failed;
 	eclass = rb_obj_class(res);
 
-#if 0
+#if 1
 	thr_crit_bup = rb_thread_critical;
 	rb_thread_critical = Qtrue;
 
 	backtrace = rb_ary_join(rb_funcall(res, rb_intern("backtrace"), 0, 0), 
 				rb_str_new2("\n"));
 	StringValue(backtrace);
-	/*###*/fprintf(stderr, RSTRING(backtrace)->ptr);
+	/*###*//* fprintf(stderr, RSTRING(backtrace)->ptr); */
 	Tcl_AddErrorInfo(interp, RSTRING(backtrace)->ptr);
 
+	/* Tcl_GlobalEval(interp, "puts {>>>}; puts $errorInfo; puts {<<}"); */
+
 	rb_thread_critical = thr_crit_bup;
 #endif
 
@@ -1842,14 +1833,32 @@
 
 
 /* destroy interpreter */
+VALUE del_root(ip)
+    Tcl_Interp *ip;
+{
+    Tcl_Preserve(ip);
+    Tcl_Eval(ip, "catch [destroy .]");
+    Tcl_Release(ip);
+    return Qnil;
+}
+
 static void
 ip_free(ptr)
     struct tcltkip *ptr;
 {
-    DUMP1("Tcl_DeleteInterp");
+    int try;
+
+    DUMP1("free Tcl Interp");
     if (ptr) {
+	Tcl_ResetResult(ptr->ip);
+	if (!Tcl_InterpDeleted(ptr->ip)) {
+	    for(try = 0; try < 5; try++) {
+		if (!Tk_GetNumMainWindows()) break;
+		rb_protect(del_root, (VALUE)(ptr->ip), 0);
+	    }
+	    Tcl_DeleteInterp(ptr->ip);
+	}
 	Tcl_Release((ClientData)ptr->ip);
-	Tcl_DeleteInterp(ptr->ip);
 	free(ptr);
     }
 }
@@ -2233,13 +2242,14 @@
 
     /* check safe-level */
     if (rb_safe_level() != q->safe_level) {
+	volatile VALUE q_dat;
 #ifdef HAVE_NATIVETHREAD
 	if (!is_ruby_native_thread()) {
 	    rb_bug("cross-thread violation on eval_queue_handler()");
 	}
 #endif
-	ret = rb_funcall(rb_proc_new(evq_safelevel_handler, 
-				     Data_Wrap_Struct(rb_cData,0,0,q)), 
+	q_dat = Data_Wrap_Struct(rb_cData,eval_queue_mark,0,q);
+	ret = rb_funcall(rb_proc_new(evq_safelevel_handler, q_dat), 
 			 rb_intern("call"), 0);
     } else {
 	DUMP2("call eval_real (for caller thread:%lx)", q->thread);
@@ -2635,10 +2645,8 @@
     /* Invoke the C procedure */
 #if TCL_MAJOR_VERSION >= 8
     if (info.isNativeObjectProc) {
-	TRAP_BEG;
-	ptr->return_value = (*info.objProc)(info.objClientData,
-					    ptr->ip, objc, objv);
-	TRAP_END;
+	ptr->return_value = (*info.objProc)(info.objClientData, ptr->ip, 
+					    objc, objv);
 
 	/* get the string value from the result object */
 	resultPtr = Tcl_GetObjResult(ptr->ip);
@@ -2649,17 +2657,14 @@
 #endif
     {
 #if TCL_MAJOR_VERSION >= 8
-	TRAP_BEG;
 	ptr->return_value = (*info.proc)(info.clientData, ptr->ip, 
 					 argc, (CONST84 char **)argv);
-	TRAP_END;
 
 	free(argv);
 
 #else /* TCL_MAJOR_VERSION < 8 */
-	TRAP_BEG;
-	ptr->return_value = (*info.proc)(info.clientData, ptr->ip, argc, argv);
-	TRAP_END;
+	ptr->return_value = (*info.proc)(info.clientData, ptr->ip, 
+					 argc, argv);
 #endif
     }
 
@@ -2862,8 +2867,9 @@
 
     /* check safe-level */
     if (rb_safe_level() != q->safe_level) {
-	ret = rb_funcall(rb_proc_new(ivq_safelevel_handler, 
-				     Data_Wrap_Struct(rb_cData,0,0,q)), 
+	volatile VALUE q_dat;
+	q_dat = Data_Wrap_Struct(rb_cData,invoke_queue_mark,0,q);
+	ret = rb_funcall(rb_proc_new(evq_safelevel_handler, q_dat), 
 			 rb_intern("call"), 0);
     } else {
 	DUMP2("call invoke_real (for caller thread:%lx)", q->thread);
@@ -3042,13 +3048,17 @@
 
 /* access Tcl variables */
 static VALUE
-ip_get_variable(self, varname, flag)
+ip_get_variable(self, varname_arg, flag_arg)
     VALUE self;
-    VALUE varname;
-    VALUE flag;
+    VALUE varname_arg;
+    VALUE flag_arg;
 {
     struct tcltkip *ptr = get_ip(self);
     int thr_crit_bup;
+    volatile VALUE varname, flag;
+
+    varname = varname_arg;
+    flag    = flag_arg;
 
     StringValue(varname);
 
@@ -3121,14 +3131,23 @@
 }
 
 static VALUE
-ip_get_variable2(self, varname, index, flag)
+ip_get_variable2(self, varname_arg, index_arg, flag_arg)
     VALUE self;
-    VALUE varname;
-    VALUE index;
-    VALUE flag;
+    VALUE varname_arg;
+    VALUE index_arg;
+    VALUE flag_arg;
 {
     struct tcltkip *ptr = get_ip(self);
     int thr_crit_bup;
+    volatile VALUE varname, index, flag;
+
+    if (index_arg == Qnil) {
+      return ip_get_variable(self, varname_arg, flag_arg);
+    }
+
+    varname = varname_arg;
+    index   = index_arg;
+    flag    = flag_arg;
 
     StringValue(varname);
     StringValue(index);
@@ -3138,7 +3157,7 @@
 	Tcl_Obj *nameobj, *idxobj, *ret;
 	char *s;
 	int  len;
-	VALUE strval;
+	volatile VALUE strval;
 
 	thr_crit_bup = rb_thread_critical;
 	rb_thread_critical = Qtrue;
@@ -3204,14 +3223,19 @@
 }
 
 static VALUE
-ip_set_variable(self, varname, value, flag)
+ip_set_variable(self, varname_arg, value_arg, flag_arg)
     VALUE self;
-    VALUE varname;
-    VALUE value;
-    VALUE flag;
+    VALUE varname_arg;
+    VALUE value_arg;
+    VALUE flag_arg;
 {
     struct tcltkip *ptr = get_ip(self);
     int thr_crit_bup;
+    volatile VALUE varname, value, flag;
+
+    varname = varname_arg;
+    value   = value_arg;
+    flag    = flag_arg;
  
     StringValue(varname);
     StringValue(value);
@@ -3221,7 +3245,7 @@
 	Tcl_Obj *nameobj, *valobj, *ret;
 	char *s;
 	int  len;
-	VALUE strval;
+	volatile VALUE strval;
 
 	thr_crit_bup = rb_thread_critical;
 	rb_thread_critical = Qtrue;
@@ -3305,15 +3329,25 @@
 }
 
 static VALUE
-ip_set_variable2(self, varname, index, value, flag)
+ip_set_variable2(self, varname_arg, index_arg, value_arg, flag_arg)
     VALUE self;
-    VALUE varname;
-    VALUE index;
-    VALUE value;
-    VALUE flag;
+    VALUE varname_arg;
+    VALUE index_arg;
+    VALUE value_arg;
+    VALUE flag_arg;
 {
     struct tcltkip *ptr = get_ip(self);
     int thr_crit_bup;
+    volatile VALUE varname, index, value, flag;
+
+    if (index_arg == Qnil) {
+      return ip_set_variable(self, varname_arg, value_arg, flag_arg);
+    }
+
+    varname = varname_arg;
+    index   = index_arg;
+    value   = value_arg;
+    flag    = flag_arg;
 
     StringValue(varname);
     StringValue(index);
@@ -3324,7 +3358,7 @@
 	Tcl_Obj *nameobj, *idxobj, *valobj, *ret;
 	char *s;
 	int  len;
-	VALUE strval;
+	volatile VALUE strval;
 
 	thr_crit_bup = rb_thread_critical;
 	rb_thread_critical = Qtrue;
@@ -3415,12 +3449,16 @@
 }
 
 static VALUE
-ip_unset_variable(self, varname, flag)
+ip_unset_variable(self, varname_arg, flag_arg)
     VALUE self;
-    VALUE varname;
-    VALUE flag;
+    VALUE varname_arg;
+    VALUE flag_arg;
 {
     struct tcltkip *ptr = get_ip(self);
+    volatile VALUE varname, value, flag;
+
+    varname = varname_arg;
+    flag    = flag_arg;
 
     StringValue(varname);
     ptr->return_value = Tcl_UnsetVar(ptr->ip, RSTRING(varname)->ptr, 
@@ -3435,13 +3473,22 @@
 }
 
 static VALUE
-ip_unset_variable2(self, varname, index, flag)
+ip_unset_variable2(self, varname_arg, index_arg, flag_arg)
     VALUE self;
-    VALUE varname;
-    VALUE index;
-    VALUE flag;
+    VALUE varname_arg;
+    VALUE index_arg;
+    VALUE flag_arg;
 {
     struct tcltkip *ptr = get_ip(self);
+    volatile VALUE varname, index, value, flag;
+
+    if (index_arg == Qnil) {
+      return ip_unset_variable(self, varname_arg, flag_arg);
+    }
+
+    varname = varname_arg;
+    index   = index_arg;
+    flag    = flag_arg;
 
     StringValue(varname);
     StringValue(index);
@@ -3823,6 +3870,7 @@
     rb_define_const(var_flag, "LEAVE_ERR_MSG",  INT2FIX(TCL_LEAVE_ERR_MSG));
     rb_define_const(var_flag, "APPEND_VALUE",   INT2FIX(TCL_APPEND_VALUE));
     rb_define_const(var_flag, "LIST_ELEMENT",   INT2FIX(TCL_LIST_ELEMENT));
+    rb_define_const(var_flag, "PARSE_VARNAME",  INT2FIX(TCL_PARSE_PART1));
 
     /* --------------------------------------------------------------- */
 


-- 
                                         永井 秀利 (九工大 知能情報)
                                             nagai@ai.kyutech.ac.jp

In This Thread