ruby-changes:21625
From: nobu <ko1@a...>
Date: Tue, 8 Nov 2011 23:27:02 +0900 (JST)
Subject: [ruby-changes:21625] nobu:r33674 (trunk): * ext/tk/tcltklib.c (rb_thread_critical): fix type.
nobu 2011-11-08 23:26:51 +0900 (Tue, 08 Nov 2011) New Revision: 33674 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=33674 Log: * ext/tk/tcltklib.c (rb_thread_critical): fix type. * ext/tk/tcltklib.c (eventloop_sleep, lib_eventloop_core): int is enough for micro seconds. may need to check overflow in the setter though. * ext/tk/tcltklib.c (RSTRING_LENINT): check overflow if necessary. * ext/tk/tcltklib.c (RbTk_ALLOC_N): wrapper for ckalloc() which takes an int. * ext/tk/tcltklib.c (ip_ruby_cmd_receiver_get, tcltklib_compile_info): get rid overflow. * ext/tk/tcltklib.c (tcltklib_compile_info): constified. Modified files: trunk/ChangeLog trunk/ext/tk/tcltklib.c Index: ChangeLog =================================================================== --- ChangeLog (revision 33673) +++ ChangeLog (revision 33674) @@ -1,3 +1,21 @@ +Tue Nov 8 23:26:49 2011 Nobuyoshi Nakada <nobu@r...> + + * ext/tk/tcltklib.c (rb_thread_critical): fix type. + + * ext/tk/tcltklib.c (eventloop_sleep, lib_eventloop_core): int is + enough for micro seconds. may need to check overflow in the + setter though. + + * ext/tk/tcltklib.c (RSTRING_LENINT): check overflow if necessary. + + * ext/tk/tcltklib.c (RbTk_ALLOC_N): wrapper for ckalloc() which + takes an int. + + * ext/tk/tcltklib.c (ip_ruby_cmd_receiver_get, tcltklib_compile_info): + get rid overflow. + + * ext/tk/tcltklib.c (tcltklib_compile_info): constified. + Tue Nov 8 20:50:45 2011 Tanaka Akira <akr@f...> * test/dbm/test_dbm.rb: split tests for read only database. Index: ext/tk/tcltklib.c =================================================================== --- ext/tk/tcltklib.c (revision 33673) +++ ext/tk/tcltklib.c (revision 33674) @@ -20,7 +20,7 @@ #endif #ifdef RUBY_VM -static VALUE rb_thread_critical; /* dummy */ +static int rb_thread_critical; /* dummy */ int rb_thread_check_trap_pending(); #else /* use rb_thread_critical on Ruby 1.8.x */ @@ -31,6 +31,9 @@ #define RSTRING_PTR(s) (RSTRING(s)->ptr) #define RSTRING_LEN(s) (RSTRING(s)->len) #endif +#if !defined(RSTRING_LENINT) +#define RSTRING_LENINT(s) ((int)RSTRING_LEN(s)) +#endif #if !defined(RARRAY_PTR) #define RARRAY_PTR(s) (RARRAY(s)->ptr) #define RARRAY_LEN(s) (RARRAY(s)->len) @@ -41,6 +44,7 @@ #else #define RbTk_OBJ_UNTRUST(x) OBJ_TAINT(x) #endif +#define RbTk_ALLOC_N(type, n) (type *)ckalloc((int)(sizeof(type) * (n))) #if defined(HAVE_RB_PROC_NEW) && !defined(RUBY_VM) /* Ruby 1.8 :: rb_proc_new() was hidden from intern.h at 2008/04/22 */ @@ -1481,7 +1485,7 @@ #if USE_RUBY_ALLOC argv = (Tcl_Obj **)ALLOC_N(Tcl_Obj *, 3); #else /* not USE_RUBY_ALLOC */ - argv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * 3); + argv = RbTk_ALLOC_N(Tcl_Obj *, 3); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)argv); /* XXXXXXXX */ #endif @@ -1521,7 +1525,7 @@ #if USE_RUBY_ALLOC argv = ALLOC_N(char *, 3); /* XXXXXXXXXX */ #else /* not USE_RUBY_ALLOC */ - argv = (CONST84 char **)ckalloc(sizeof(char *) * 3); + argv = RbTk_ALLOC_N(CONST84 char *, 3); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)argv); /* XXXXXXXX */ #endif @@ -1560,7 +1564,7 @@ #if USE_RUBY_ALLOC argv = (char **)ALLOC_N(char *, 3); #else /* not USE_RUBY_ALLOC */ - argv = (char **)ckalloc(sizeof(char *) * 3); + argv = RbTk_ALLOC_N(char *, 3); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)argv); /* XXXXXXXX */ #endif @@ -2062,7 +2066,7 @@ } t.tv_sec = 0; - t.tv_usec = (long)(no_event_wait*1000.0); + t.tv_usec = (int)(no_event_wait*1000.0); #ifdef HAVE_NATIVETHREAD #ifndef RUBY_USE_NATIVE_THREAD @@ -2193,7 +2197,7 @@ if (update_flag) DUMP1("update loop start!!"); t.tv_sec = 0; - t.tv_usec = 1000 * (long)no_event_wait; + t.tv_usec = 1000 * no_event_wait; Tcl_DeleteTimerHandler(timer_token); run_timer_flag = 0; @@ -2676,7 +2680,7 @@ { volatile VALUE parent_evloop = eventloop_thread; struct evloop_params *args = ALLOC(struct evloop_params); - /* struct evloop_params *args = (struct evloop_params *)ckalloc(sizeof(struct evloop_params)); */ + /* struct evloop_params *args = RbTk_ALLOC_N(struct evloop_params, 1); */ tcl_stubs_check(); @@ -2956,10 +2960,10 @@ } q = (struct thread_call_proc_arg *)ALLOC(struct thread_call_proc_arg); - /* q = (struct thread_call_proc_arg *)ckalloc(sizeof(struct thread_call_proc_arg)); */ + /* q = RbTk_ALLOC_N(struct thread_call_proc_arg, 1); */ q->proc = proc; q->done = (int*)ALLOC(int); - /* q->done = (int*)ckalloc(sizeof(int)); */ + /* q->done = RbTk_ALLOC_N(int, 1); */ *(q->done) = 0; /* create call-proc thread */ @@ -3121,14 +3125,14 @@ /* buf = ALLOC_N(char, (RSTRING(msg)->len)+1);*/ /* memcpy(buf, RSTRING(msg)->ptr, RSTRING(msg)->len);*/ /* buf[RSTRING(msg)->len] = 0; */ - buf = ALLOC_N(char, RSTRING_LEN(msg)+1); - /* buf = ckalloc(sizeof(char)*((RSTRING_LEN(msg))+1)); */ + buf = ALLOC_N(char, RSTRING_LENINT(msg)+1); + /* buf = ckalloc(RSTRING_LENINT(msg)+1); */ memcpy(buf, RSTRING_PTR(msg), RSTRING_LEN(msg)); buf[RSTRING_LEN(msg)] = 0; Tcl_DStringInit(&dstr); Tcl_DStringFree(&dstr); - Tcl_ExternalToUtfDString(encoding, buf, RSTRING_LEN(msg), &dstr); + Tcl_ExternalToUtfDString(encoding, buf, RSTRING_LENINT(msg), &dstr); Tcl_AppendResult(interp, Tcl_DStringValue(&dstr), (char*)NULL); DUMP2("error message:%s", Tcl_DStringValue(&dstr)); @@ -3555,7 +3559,7 @@ } else { /* global variable omitted '$' */ char *buf; - int len; + size_t len; len = strlen(str); buf = ALLOC_N(char, len + 2); @@ -3677,7 +3681,7 @@ /* allocate */ arg = ALLOC(struct cmd_body_arg); - /* arg = (struct cmd_body_arg *)ckalloc(sizeof(struct cmd_body_arg)); */ + /* arg = RbTk_ALLOC_N(struct cmd_body_arg, 1); */ arg->receiver = receiver; arg->method = method; @@ -4116,7 +4120,7 @@ DUMP1("pass argument check"); /* param = (struct th_update_param *)Tcl_Alloc(sizeof(struct th_update_param)); */ - param = (struct th_update_param *)ckalloc(sizeof(struct th_update_param)); + param = RbTk_ALLOC_N(struct th_update_param, 1); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)param); #endif @@ -4980,7 +4984,7 @@ rb_thread_critical = Qtrue; /* param = (struct th_vwait_param *)Tcl_Alloc(sizeof(struct th_vwait_param)); */ - param = (struct th_vwait_param *)ckalloc(sizeof(struct th_vwait_param)); + param = RbTk_ALLOC_N(struct th_vwait_param, 1); #if 1 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)param); #endif @@ -5196,7 +5200,7 @@ #endif /* param = (struct th_vwait_param *)Tcl_Alloc(sizeof(struct th_vwait_param)); */ - param = (struct th_vwait_param *)ckalloc(sizeof(struct th_vwait_param)); + param = RbTk_ALLOC_N(struct th_vwait_param, 1); #if 1 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)param); #endif @@ -6042,7 +6046,7 @@ char **argv; /* argv = (char **)Tcl_Alloc(sizeof(char *) * (objc + 1)); */ - argv = (char **)ckalloc(sizeof(char *) * (objc + 1)); + argv = RbTk_ALLOC_N(char *, (objc + 1)); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)argv); /* XXXXXXXX */ #endif @@ -6151,7 +6155,7 @@ /* create object */ Data_Get_Struct(self, struct tcltkip, ptr); ptr = ALLOC(struct tcltkip); - /* ptr = (struct tcltkip *)ckalloc(sizeof(struct tcltkip)); */ + /* ptr = RbTk_ALLOC_N(struct tcltkip, 1); */ DATA_PTR(self) = ptr; #ifdef RUBY_USE_NATIVE_THREAD ptr->tk_thread_id = 0; @@ -6388,7 +6392,7 @@ { struct tcltkip *master = get_ip(interp); struct tcltkip *slave = ALLOC(struct tcltkip); - /* struct tcltkip *slave = (struct tcltkip *)ckalloc(sizeof(struct tcltkip)); */ + /* struct tcltkip *slave = RbTk_ALLOC_N(struct tcltkip, 1); */ VALUE safemode; VALUE name; int safe; @@ -6928,22 +6932,22 @@ StringValue(enc); if (strcmp(RSTRING_PTR(enc), "binary") == 0) { /* binary string */ - return Tcl_NewByteArrayObj((const unsigned char *)s, RSTRING_LEN(str)); + return Tcl_NewByteArrayObj((const unsigned char *)s, RSTRING_LENINT(str)); } else { /* text string */ - return Tcl_NewStringObj(s, RSTRING_LEN(str)); + return Tcl_NewStringObj(s, RSTRING_LENINT(str)); } #ifdef HAVE_RUBY_ENCODING_H } else if (rb_enc_get_index(str) == ENCODING_INDEX_BINARY) { /* binary string */ - return Tcl_NewByteArrayObj((const unsigned char *)s, RSTRING_LEN(str)); + return Tcl_NewByteArrayObj((const unsigned char *)s, RSTRING_LENINT(str)); #endif } else if (memchr(s, 0, RSTRING_LEN(str))) { /* probably binary string */ - return Tcl_NewByteArrayObj((const unsigned char *)s, RSTRING_LEN(str)); + return Tcl_NewByteArrayObj((const unsigned char *)s, RSTRING_LENINT(str)); } else { /* probably text string */ - return Tcl_NewStringObj(s, RSTRING_LEN(str)); + return Tcl_NewStringObj(s, RSTRING_LENINT(str)); } #endif } @@ -7149,7 +7153,7 @@ /* allocate memory (argv cross over thread : must be in heap) */ if (argv) { /* VALUE *temp = ALLOC_N(VALUE, argc); */ - VALUE *temp = (VALUE*)ckalloc(sizeof(VALUE) * argc); + VALUE *temp = RbTk_ALLOC_N(VALUE, argc); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)temp); /* XXXXXXXX */ #endif @@ -7159,7 +7163,7 @@ /* allocate memory (keep result) */ /* alloc_done = (int*)ALLOC(int); */ - alloc_done = (int*)ckalloc(sizeof(int)); + alloc_done = RbTk_ALLOC_N(int, 1); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)alloc_done); /* XXXXXXXX */ #endif @@ -7167,7 +7171,7 @@ /* allocate memory (freed by Tcl_ServiceEvent) */ /* callq = (struct call_queue *)Tcl_Alloc(sizeof(struct call_queue)); */ - callq = (struct call_queue *)ckalloc(sizeof(struct call_queue)); + callq = RbTk_ALLOC_N(struct call_queue, 1); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve(callq); #endif @@ -7632,7 +7636,7 @@ } else { DUMP2("eval from current eventloop %lx", current); } - result = ip_eval_real(self, RSTRING_PTR(str), RSTRING_LEN(str)); + result = ip_eval_real(self, RSTRING_PTR(str), RSTRING_LENINT(str)); if (rb_obj_is_kind_of(result, rb_eException)) { rb_exc_raise(result); } @@ -7646,14 +7650,14 @@ /* allocate memory (keep result) */ /* alloc_done = (int*)ALLOC(int); */ - alloc_done = (int*)ckalloc(sizeof(int)); + alloc_done = RbTk_ALLOC_N(int, 1); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)alloc_done); /* XXXXXXXX */ #endif *alloc_done = 0; /* eval_str = ALLOC_N(char, RSTRING_LEN(str) + 1); */ - eval_str = ckalloc(sizeof(char) * (RSTRING_LEN(str) + 1)); + eval_str = ckalloc(RSTRING_LENINT(str) + 1); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)eval_str); /* XXXXXXXX */ #endif @@ -7662,7 +7666,7 @@ /* allocate memory (freed by Tcl_ServiceEvent) */ /* evq = (struct eval_queue *)Tcl_Alloc(sizeof(struct eval_queue)); */ - evq = (struct eval_queue *)ckalloc(sizeof(struct eval_queue)); + evq = RbTk_ALLOC_N(struct eval_queue, 1); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve(evq); #endif @@ -7673,7 +7677,7 @@ /* construct event data */ evq->done = alloc_done; evq->str = eval_str; - evq->len = RSTRING_LEN(str); + evq->len = RSTRING_LENINT(str); evq->interp = ip_obj; evq->result = result; evq->thread = current; @@ -8055,14 +8059,14 @@ return str; } buf = ALLOC_N(char, RSTRING_LEN(str)+1); - /* buf = ckalloc(sizeof(char) * (RSTRING_LEN(str)+1)); */ + /* buf = ckalloc(sizeof(char) * (RSTRING_LENINT(str)+1)); */ memcpy(buf, RSTRING_PTR(str), RSTRING_LEN(str)); buf[RSTRING_LEN(str)] = 0; Tcl_DStringInit(&dstr); Tcl_DStringFree(&dstr); /* Tcl_ExternalToUtfDString(encoding,buf,strlen(buf),&dstr); */ - Tcl_ExternalToUtfDString(encoding, buf, RSTRING_LEN(str), &dstr); + Tcl_ExternalToUtfDString(encoding, buf, RSTRING_LENINT(str), &dstr); /* str = rb_tainted_str_new2(Tcl_DStringValue(&dstr)); */ /* str = rb_str_new2(Tcl_DStringValue(&dstr)); */ @@ -8210,7 +8214,7 @@ int len; StringValue(str); - tclstr = Tcl_NewStringObj(RSTRING_PTR(str), RSTRING_LEN(str)); + tclstr = Tcl_NewStringObj(RSTRING_PTR(str), RSTRING_LENINT(str)); Tcl_IncrRefCount(tclstr); s = (char*)Tcl_GetByteArrayFromObj(tclstr, &len); str = rb_tainted_str_new(s, len); @@ -8246,14 +8250,14 @@ } buf = ALLOC_N(char, RSTRING_LEN(str)+1); - /* buf = ckalloc(sizeof(char) * (RSTRING_LEN(str)+1)); */ + /* buf = ckalloc(sizeof(char) * (RSTRING_LENINT(str)+1)); */ memcpy(buf, RSTRING_PTR(str), RSTRING_LEN(str)); buf[RSTRING_LEN(str)] = 0; Tcl_DStringInit(&dstr); Tcl_DStringFree(&dstr); /* Tcl_UtfToExternalDString(encoding,buf,strlen(buf),&dstr); */ - Tcl_UtfToExternalDString(encoding,buf,RSTRING_LEN(str),&dstr); + Tcl_UtfToExternalDString(encoding,buf,RSTRING_LENINT(str),&dstr); /* str = rb_tainted_str_new2(Tcl_DStringValue(&dstr)); */ /* str = rb_str_new2(Tcl_DStringValue(&dstr)); */ @@ -8342,7 +8346,7 @@ rb_thread_critical = Qtrue; /* src_buf = ALLOC_N(char, RSTRING_LEN(str)+1); */ - src_buf = ckalloc(sizeof(char) * (RSTRING_LEN(str)+1)); + src_buf = ckalloc(RSTRING_LENINT(str)+1); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)src_buf); /* XXXXXXXX */ #endif @@ -8350,7 +8354,7 @@ src_buf[RSTRING_LEN(str)] = 0; /* dst_buf = ALLOC_N(char, RSTRING_LEN(str)+1); */ - dst_buf = ckalloc(sizeof(char) * (RSTRING_LEN(str)+1)); + dst_buf = ckalloc(RSTRING_LENINT(str)+1); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)dst_buf); /* XXXXXXXX */ #endif @@ -8487,7 +8491,7 @@ if (!inf->cmdinfo.isNativeObjectProc) { /* string interface */ /* argv = (char **)ALLOC_N(char *, argc+1);*/ /* XXXXXXXXXX */ - argv = (char **)ckalloc(sizeof(char *)*(argc+1)); + argv = RbTk_ALLOC_N(char *, (argc+1)); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)argv); /* XXXXXXXX */ #endif @@ -8633,7 +8637,7 @@ #if TCL_MAJOR_VERSION >= 8 /* unknown_objv = (Tcl_Obj **)ALLOC_N(Tcl_Obj *, objc+2); */ - unknown_objv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc+2)); + unknown_objv = RbTk_ALLOC_N(Tcl_Obj *, (objc+2)); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)unknown_objv); /* XXXXXXXX */ #endif @@ -8644,7 +8648,7 @@ objv = unknown_objv; #else /* unknown_argv = (char **)ALLOC_N(char *, argc+2); */ - unknown_argv = (char **)ckalloc(sizeof(char *) * (argc+2)); + unknown_argv = RbTk_ALLOC_N(char *, (argc+2)); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)unknown_argv); /* XXXXXXXX */ #endif @@ -8701,7 +8705,7 @@ /* string interface */ /* argv = (char **)ALLOC_N(char *, argc+1); */ - argv = (char **)ckalloc(sizeof(char *) * (argc+1)); + argv = RbTk_ALLOC_N(char *, (argc+1)); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)argv); /* XXXXXXXX */ #endif @@ -8846,7 +8850,7 @@ /* memory allocation */ #if TCL_MAJOR_VERSION >= 8 /* av = ALLOC_N(Tcl_Obj *, argc+1);*/ /* XXXXXXXXXX */ - av = (Tcl_Obj**)ckalloc(sizeof(Tcl_Obj *)*(argc+1)); + av = RbTk_ALLOC_N(Tcl_Obj *, (argc+1)); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)av); /* XXXXXXXX */ #endif @@ -8859,7 +8863,7 @@ #else /* TCL_MAJOR_VERSION < 8 */ /* string interface */ /* av = ALLOC_N(char *, argc+1); */ - av = (char**)ckalloc(sizeof(char *) * (argc+1)); + av = RbTk_ALLOC_N(char *, (argc+1)); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)av); /* XXXXXXXX */ #endif @@ -9139,7 +9143,7 @@ /* allocate memory (keep result) */ /* alloc_done = (int*)ALLOC(int); */ - alloc_done = (int*)ckalloc(sizeof(int)); + alloc_done = RbTk_ALLOC_N(int, 1); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)alloc_done); /* XXXXXXXX */ #endif @@ -9147,7 +9151,7 @@ /* allocate memory (freed by Tcl_ServiceEvent) */ /* ivq = (struct invoke_queue *)Tcl_Alloc(sizeof(struct invoke_queue)); */ - ivq = (struct invoke_queue *)ckalloc(sizeof(struct invoke_queue)); + ivq = RbTk_ALLOC_N(struct invoke_queue, 1); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)ivq); /* XXXXXXXX */ #endif @@ -9869,7 +9873,7 @@ /* based on Tcl/Tk's Tcl_Merge() */ /* flagPtr = ALLOC_N(int, argc); */ - flagPtr = (int *)ckalloc(sizeof(int) * argc); + flagPtr = RbTk_ALLOC_N(int, argc); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)flagPtr); /* XXXXXXXXXX */ #endif @@ -9880,7 +9884,7 @@ if (OBJ_TAINTED(argv[num])) taint_flag = 1; dst = StringValuePtr(argv[num]); #if TCL_MAJOR_VERSION >= 8 - len += Tcl_ScanCountedElement(dst, RSTRING_LEN(argv[num]), + len += Tcl_ScanCountedElement(dst, RSTRING_LENINT(argv[num]), &flagPtr[num]) + 1; #else /* TCL_MAJOR_VERSION < 8 */ len += Tcl_ScanElement(dst, &flagPtr[num]) + 1; @@ -9897,7 +9901,7 @@ for(num = 0; num < argc; num++) { #if TCL_MAJOR_VERSION >= 8 len = Tcl_ConvertCountedElement(RSTRING_PTR(argv[num]), - RSTRING_LEN(argv[num]), + RSTRING_LENINT(argv[num]), dst, flagPtr[num]); #else /* TCL_MAJOR_VERSION < 8 */ len = Tcl_ConvertElement(RSTRING_PTR(argv[num]), dst, flagPtr[num]); @@ -9961,10 +9965,10 @@ StringValue(src); #if TCL_MAJOR_VERSION >= 8 - len = Tcl_ScanCountedElement(RSTRING_PTR(src), RSTRING_LEN(src), + len = Tcl_ScanCountedElement(RSTRING_PTR(src), RSTRING_LENINT(src), &scan_flag); dst = rb_str_new(0, len + 1); - len = Tcl_ConvertCountedElement(RSTRING_PTR(src), RSTRING_LEN(src), + len = Tcl_ConvertCountedElement(RSTRING_PTR(src), RSTRING_LENINT(src), RSTRING_PTR(dst), scan_flag); #else /* TCL_MAJOR_VERSION < 8 */ len = Tcl_ScanElement(RSTRING_PTR(src), &scan_flag); @@ -10015,8 +10019,8 @@ tcltklib_compile_info() { volatile VALUE ret; - int size; - char form[] + size_t size; + static CONST char form[] = "tcltklib %s :: Ruby%s (%s) %s pthread :: Tcl%s(%s)/Tk%s(%s) %s"; char *info; -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/