From 9e48333190cb95ecd4d8a49eed103518457e8ace Mon Sep 17 00:00:00 2001 From: matz Date: Mon, 27 Apr 1998 10:04:11 +0000 Subject: tcltklib/gtk git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/v1_1r@193 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 18 +++++++++++ array.c | 26 ++++++++++------ dir.c | 8 +++-- eval.c | 5 ++-- ext/gtk/gtk.c | 40 +++++++++++-------------- ext/gtk/test2.rb | 4 +-- ext/tcltklib/tcltklib.c | 21 ++++++------- file.c | 58 ++++++++++++++---------------------- hash.c | 55 +++++++++++++++++++++++++++------- intern.h | 1 + io.c | 6 +--- lib/telnet.rb | 52 ++++++++++++++++---------------- lib/tk.rb | 79 ++++++++++++++++++++++++++++--------------------- object.c | 66 +++++++++++++++++++++-------------------- random.c | 23 ++++++++------ ruby.h | 8 ++--- string.c | 65 +++++++++++++++++++--------------------- variable.c | 5 +--- 18 files changed, 297 insertions(+), 243 deletions(-) diff --git a/ChangeLog b/ChangeLog index 85055c7527..26abd38487 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,23 @@ +Mon Apr 27 16:59:17 1998 Yukihiro Matsumoto + + * ext/gtk/gtk.c (Init_gtk): use timeout, not idle to avoid + comsuming CPU too much. + + * lib/tk.rb: use tcltklib#_invoke instead of `_eval'. + +Mon Apr 27 13:46:27 1998 Tadahiro Maebashi + + * ext/tcltklib/tcltklib.c (ip_invoke): invoke tcl command + directly. need not worry about escaping tcl characters. + +Mon Apr 27 12:04:43 1998 Yukihiro Matsumoto + + * random.c (f_rand): do not call srand() implicitly. + Fri Apr 24 14:35:45 1998 Yukihiro Matsumoto + * experimental release 1.1b9_15. + * parse.y (assignable): dyna_var_asgn actually defines nested local variables in outer context. diff --git a/array.c b/array.c index ca6ab3cad6..651a2cbee4 100644 --- a/array.c +++ b/array.c @@ -599,6 +599,13 @@ ary_dup(ary) return ary_new4(RARRAY(ary)->len, RARRAY(ary)->ptr); } +static VALUE +to_ary(ary) + VALUE ary; +{ + return rb_convert_type(ary, T_ARRAY, "Array", "to_ary"); +} + extern VALUE OFS; VALUE @@ -720,7 +727,7 @@ static VALUE ary_reverse_method(ary) VALUE ary; { - return ary_reverse(ary_clone(ary)); + return ary_reverse(ary_dup(ary)); } static ID cmp; @@ -767,7 +774,7 @@ ary_sort(ary) VALUE ary; { if (RARRAY(ary)->len == 0) return ary; - return ary_sort_bang(ary_clone(ary)); + return ary_sort_bang(ary_dup(ary)); } VALUE @@ -857,7 +864,7 @@ static VALUE ary_replace_method(ary, ary2) VALUE ary, ary2; { - Check_Type(ary2, T_ARRAY); + ary2 = to_ary(ary2); ary_replace(ary, 0, RARRAY(ary2)->len, ary2); return ary; } @@ -1084,7 +1091,7 @@ ary_cmp(ary, ary2) { int i, len; - Check_Type(ary2, T_ARRAY); + ary2 = to_ary(ary2); len = RARRAY(ary)->len; if (len > RARRAY(ary2)->len) { len = RARRAY(ary2)->len; @@ -1108,7 +1115,7 @@ ary_diff(ary1, ary2) VALUE ary3; int i; - Check_Type(ary2, T_ARRAY); + ary2 = to_ary(ary2); ary3 = ary_new(); for (i=0; ilen; i++) { if (ary_includes(ary2, RARRAY(ary1)->ptr[i])) continue; @@ -1125,7 +1132,7 @@ ary_and(ary1, ary2) VALUE ary3; int i; - Check_Type(ary2, T_ARRAY); + ary2 = to_ary(ary2); ary3 = ary_new(); for (i=0; ilen; i++) { if (ary_includes(ary2, RARRAY(ary1)->ptr[i]) @@ -1194,7 +1201,7 @@ static VALUE ary_uniq(ary) VALUE ary; { - VALUE v = ary_uniq_bang(ary_clone(ary)); + VALUE v = ary_uniq_bang(ary_dup(ary)); if (NIL_P(v)) return ary; return v; @@ -1226,7 +1233,7 @@ static VALUE ary_compact(ary) VALUE ary; { - VALUE v = ary_compact_bang(ary_clone(ary)); + VALUE v = ary_compact_bang(ary_dup(ary)); if (NIL_P(v)) return ary; return v; @@ -1271,7 +1278,7 @@ static VALUE ary_flatten(ary) VALUE ary; { - VALUE v = ary_flatten_bang(ary_clone(ary)); + VALUE v = ary_flatten_bang(ary_dup(ary)); if (NIL_P(v)) return ary; return v; @@ -1290,6 +1297,7 @@ Init_Array() rb_define_method(cArray, "to_s", ary_to_s, 0); rb_define_method(cArray, "inspect", ary_inspect, 0); rb_define_method(cArray, "to_a", ary_to_a, 0); + rb_define_method(cArray, "to_ary", ary_to_a, 0); rb_define_method(cArray, "freeze", ary_freeze, 0); rb_define_method(cArray, "frozen?", ary_frozen_p, 0); diff --git a/dir.c b/dir.c index 4c380e6b98..17c6515484 100644 --- a/dir.c +++ b/dir.c @@ -83,8 +83,9 @@ dir_s_open(dir_class, dirname) obj = Data_Wrap_Struct(dir_class, 0, free_dir, dirp); - if (iterator_p()) + if (iterator_p()) { rb_ensure(rb_yield, obj, dir_close, obj); + } return obj; } @@ -112,9 +113,10 @@ dir_read(dir) dp = readdir(dirp); if (dp) return str_taint(str_new(dp->d_name, NAMLEN(dp))); + else if (errno == 0) { /* end of stream */ + return Qnil; + } else { - if (errno == 0) /* end of stream */ - return Qnil; rb_sys_fail(0); } } diff --git a/eval.c b/eval.c index 2ff7932a60..c3d4b1604b 100644 --- a/eval.c +++ b/eval.c @@ -452,14 +452,15 @@ new_dvar(id, value) { NEWOBJ(vars, struct RVarmap); OBJSETUP(vars, 0, T_VARMAP); - vars->val = value; if (id == 0) { vars->id = (ID)value; + vars->val = 0; vars->next = the_dyna_vars; the_dyna_vars = vars; } else if (the_dyna_vars) { vars->id = id; + vars->val = value; vars->next = the_dyna_vars->next; the_dyna_vars->next = vars; } @@ -1722,7 +1723,7 @@ rb_eval(self, node) POP_ITER(); } } - else if (the_block->tag->dst == state) { + else if (_block.tag->dst == state) { state &= TAG_MASK; if (state == TAG_RETURN) { result = prot_tag->retval; diff --git a/ext/gtk/gtk.c b/ext/gtk/gtk.c index b72620de80..41e6874e19 100644 --- a/ext/gtk/gtk.c +++ b/ext/gtk/gtk.c @@ -1105,7 +1105,7 @@ signal_callback(widget, data, nparams, params) { VALUE self = get_value_from_gobject(GTK_OBJECT(widget)); VALUE proc = RARRAY(data)->ptr[0]; - VALUE a = RARRAY(data)->ptr[3]; + VALUE a = RARRAY(data)->ptr[2]; ID id = NUM2INT(RARRAY(data)->ptr[1]); VALUE result = Qnil; VALUE args = ary_new2(nparams+1+RARRAY(a)->len); @@ -1152,7 +1152,7 @@ gobj_smethod_added(self, id) char *name = rb_id2name(NUM2INT(id)); if (gtk_signal_lookup(name, GTK_OBJECT_TYPE(obj))) { - VALUE data = assoc_new(Qnil, id); + VALUE data = ary_new3(3, Qnil, id, ary_new2(0)); add_relative(self, data); gtk_signal_connect_interp(obj, name, @@ -5729,6 +5729,9 @@ static gint idle() { CHECK_INTS; +#ifdef THREAD + if (!thread_critical) thread_schedule(); +#endif return TRUE; } @@ -5740,20 +5743,13 @@ exec_interval(proc) } static VALUE -timeout_add(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; +timeout_add(self, interval) + VALUE self, interval; { - VALUE interval, func; int id; - rb_scan_args(argc, argv, "11", &interval, &func); - if (NIL_P(func)) { - func = f_lambda(); - } id = gtk_timeout_add_interp(NUM2INT(interval), exec_interval, - (gpointer)func, 0); + (gpointer)f_lambda(), 0); return INT2FIX(id); } @@ -5766,19 +5762,12 @@ timeout_remove(self, id) } static VALUE -idle_add(argc, argv, self) - int argc; - VALUE *argv; +idle_add(self) VALUE self; { - VALUE func; int id; - rb_scan_args(argc, argv, "01", &func); - if (NIL_P(func)) { - func = f_lambda(); - } - id = gtk_idle_add_interp(exec_interval, (gpointer)func, 0); + id = gtk_idle_add_interp(exec_interval, (gpointer)f_lambda(), 0); return INT2FIX(id); } @@ -6624,9 +6613,9 @@ Init_gtk() /* Gtk module */ rb_define_module_function(mGtk, "main", gtk_m_main, 0); - rb_define_module_function(mGtk, "timeout_add", timeout_add, -1); + rb_define_module_function(mGtk, "timeout_add", timeout_add, 1); rb_define_module_function(mGtk, "timeout_remove", timeout_remove, 1); - rb_define_module_function(mGtk, "idle_add", idle_add, -1); + rb_define_module_function(mGtk, "idle_add", idle_add, 0); rb_define_module_function(mGtk, "idle_remove", idle_remove, 1); rb_define_module_function(mGtk, "set_warning_handler", @@ -6839,7 +6828,12 @@ Init_gtk() id_call = rb_intern("call"); id_gtkdata = rb_intern("gtkdata"); id_relatives = rb_intern("relatives"); +#if 0 gtk_idle_add((GtkFunction)idle, 0); +#else + /* use timeout to avoid busy wait */ + gtk_timeout_add(1, (GtkFunction)idle, 0); +#endif g_set_error_handler(gtkerr); g_set_warning_handler(gtkerr); diff --git a/ext/gtk/test2.rb b/ext/gtk/test2.rb index 170de96185..33215b7f7a 100644 --- a/ext/gtk/test2.rb +++ b/ext/gtk/test2.rb @@ -58,8 +58,8 @@ button.set_flags(Gtk::CAN_FOCUS); button.signal_connect("clicked") do tmp_list = list.selection list.remove_items(tmp_list) - for i in tmp_list - i.destroy + for w in tmp_list + w.destroy end end box2.pack_start(button, FALSE, TRUE, 0) diff --git a/ext/tcltklib/tcltklib.c b/ext/tcltklib/tcltklib.c index b63b1d06dd..6cb017a398 100644 --- a/ext/tcltklib/tcltklib.c +++ b/ext/tcltklib/tcltklib.c @@ -37,12 +37,12 @@ int *tclDummyMathPtr = (int *) matherr; typedef struct { Tcl_TimerToken token; int flag; -} Tk_ThreadTimerData; +} Tk_TimerData; /* timer callback */ -void _timer_for_thread (ClientData clientData) +void _timer_for_tcl (ClientData clientData) { - Tk_ThreadTimerData *timer = (Tk_ThreadTimerData *) clientData; + Tk_TimerData *timer = (Tk_TimerData*)clientData; timer->flag = 0; CHECK_INTS; @@ -50,8 +50,8 @@ void _timer_for_thread (ClientData clientData) if (!thread_critical) thread_schedule(); #endif - timer->token = Tk_CreateTimerHandler(200, _timer_for_thread, - (ClientData) timer); + timer->token = Tk_CreateTimerHandler(200, _timer_for_tcl, + (ClientData)timer); timer->flag = 1; } @@ -59,12 +59,12 @@ void _timer_for_thread (ClientData clientData) static VALUE lib_mainloop(VALUE self) { - Tk_ThreadTimerData *timer; + Tk_TimerData *timer; - timer = (Tk_ThreadTimerData *) ckalloc(sizeof(Tk_ThreadTimerData)); + timer = (Tk_TimerData *) ckalloc(sizeof(Tk_TimerData)); timer->flag = 0; - timer->token = Tk_CreateTimerHandler(200, _timer_for_thread, - (ClientData) timer); + timer->token = Tk_CreateTimerHandler(200, _timer_for_tcl, + (ClientData)timer); timer->flag = 1; DUMP1("start Tk_Mainloop"); @@ -219,7 +219,7 @@ ip_invoke(int argc, VALUE *argv, VALUE obj) av = (char **)ALLOCA_N(char **, argc+1); for (i = 0; i < argc; ++i) { - char *s = CTR2CSTR(argv[i]); + char *s = STR2CSTR(argv[i]); av[i] = ALLOCA_N(char, strlen(s)+1); strcpy(av[i], s); @@ -230,6 +230,7 @@ ip_invoke(int argc, VALUE *argv, VALUE obj) NameError("invalid command name `%s'", av[0]); } + Tcl_ResetResult(ptr->ip); ptr->return_value = (*info.proc)(info.clientData, ptr->ip, argc, av); if (ptr->return_value == TCL_ERROR) { diff --git a/file.c b/file.c index 2865ef6899..c26107aa98 100644 --- a/file.c +++ b/file.c @@ -90,8 +90,7 @@ file_s_open(argc, argv, klass) rb_scan_args(argc, argv, "11", &fname, &vmode); Check_SafeStr(fname); if (!NIL_P(vmode)) { - Check_Type(vmode, T_STRING); - mode = RSTRING(vmode)->ptr; + mode = STR2CSTR(vmode); } else { mode = "r"; @@ -125,8 +124,7 @@ file_reopen(argc, argv, file) Check_SafeStr(fname); if (!NIL_P(nmode)) { - Check_Type(nmode, T_STRING); - mode = RSTRING(nmode)->ptr; + mode = STR2CSTR(nmode); } else { mode = "r"; @@ -305,19 +303,12 @@ rb_stat(file, st) { OpenFile *fptr; - switch (TYPE(file)) { - case T_STRING: - Check_SafeStr(file); - return stat(RSTRING(file)->ptr, st); - break; - case T_FILE: + if (TYPE(file) == T_FILE) { GetOpenFile(file, fptr); return fstat(fileno(fptr->f), st); - break; - default: - Check_Type(file, T_STRING); } - return -1; /* not reached */ + Check_SafeStr(file); + return stat(RSTRING(file)->ptr, st); } static VALUE @@ -757,9 +748,8 @@ static VALUE test_sticky(obj, fname) VALUE obj, fname; { - Check_Type(fname, T_STRING); #ifdef S_ISVTX - return check3rdbyte(RSTRING(fname)->ptr, S_ISVTX); + return check3rdbyte(STR2CSTR(fname), S_ISVTX); #else return FALSE; #endif @@ -1183,9 +1173,7 @@ file_s_expand_path(obj, fname) char *s, *p; char buf[MAXPATHLEN+2]; - Check_Type(fname, T_STRING); - s = RSTRING(fname)->ptr; - + s = STR2CSTR(fname); p = buf; if (s[0] == '~') { if (s[1] == '/' || @@ -1300,24 +1288,24 @@ file_s_basename(argc, argv) int argc; VALUE *argv; { - VALUE fname, ext; - char *p; + VALUE fname, fext; + char *name, *p, *ext; int f; - rb_scan_args(argc, argv, "11", &fname, &ext); - Check_Type(fname, T_STRING); - if (!NIL_P(ext)) Check_Type(ext, T_STRING); - p = strrchr(RSTRING(fname)->ptr, '/'); + rb_scan_args(argc, argv, "11", &fname, &fext); + name = STR2CSTR(fname); + if (!NIL_P(fext)) ext = STR2CSTR(fext); + p = strrchr(name, '/'); if (!p) { - if (!NIL_P(ext)) { - f = rmext(RSTRING(fname)->ptr, RSTRING(ext)->ptr); - if (f) return str_new(RSTRING(fname)->ptr, f); + if (!NIL_P(fext)) { + f = rmext(name, ext); + if (f) return str_new(name, f); } return fname; } p++; /* skip last `/' */ - if (!NIL_P(ext)) { - f = rmext(p, RSTRING(ext)->ptr); + if (!NIL_P(fext)) { + f = rmext(p, ext); if (f) return str_new(p, f); } return str_taint(str_new2(p)); @@ -1327,16 +1315,16 @@ static VALUE file_s_dirname(obj, fname) VALUE obj, fname; { - UCHAR *p; + UCHAR *name, *p; - Check_Type(fname, T_STRING); - p = strrchr(RSTRING(fname)->ptr, '/'); + name = STR2CSTR(fname); + p = strrchr(name, '/'); if (!p) { return str_new2("."); } - if (p == RSTRING(fname)->ptr) + if (p == name) p++; - return str_taint(str_new(RSTRING(fname)->ptr, p - RSTRING(fname)->ptr)); + return str_taint(str_new(name, p - name)); } static VALUE diff --git a/hash.c b/hash.c index e1f5939e77..3ce2aae386 100644 --- a/hash.c +++ b/hash.c @@ -298,6 +298,13 @@ hash_dup(hash) return (VALUE)hash2; } +static VALUE +to_hash(hash) + VALUE hash; +{ + return rb_convert_type(hash, T_HASH, "Hash", "to_hash"); +} + static int hash_rehash_i(key, value, tbl) VALUE key, value; @@ -468,7 +475,7 @@ static VALUE hash_replace(hash, hash2) VALUE hash, hash2; { - Check_Type(hash2, T_HASH); + hash2 = to_hash(hash2); hash_clear(hash); st_foreach(RHASH(hash2)->tbl, replace_i, hash); @@ -602,6 +609,13 @@ hash_to_s(hash) return ary_to_s(hash_to_a(hash)); } +static VALUE +hash_to_hash(hash) + VALUE hash; +{ + return hash; +} + static int keys_i(key, value, ary) VALUE key, value, ary; @@ -755,8 +769,7 @@ static VALUE hash_update(hash1, hash2) VALUE hash1, hash2; { - Check_Type(hash2, T_HASH); - + hash2 = to_hash(hash2); st_foreach(RHASH(hash2)->tbl, hash_update_i, hash1); return hash1; } @@ -776,8 +789,7 @@ env_delete(obj, name) char *nam, *val = 0; rb_secure(4); - Check_Type(name, T_STRING); - nam = RSTRING(name)->ptr; + nam = STR2CSTR(name); len = strlen(nam); if (strcmp(nam, "PATH") == 0) path_tainted = 0; for(i=0; environ[i]; i++) { @@ -809,16 +821,16 @@ static VALUE f_getenv(obj, name) VALUE obj, name; { - char *env; + char *nam, *env; + int len; - Check_Type(name, T_STRING); - - if (strlen(RSTRING(name)->ptr) != RSTRING(name)->len) + nam = str2cstr(name, &len); + if (strlen(nam) != len) ArgError("Bad environment name"); - env = getenv(RSTRING(name)->ptr); + env = getenv(nam); if (env) { - if (strcmp(RSTRING(name)->ptr, "PATH") == 0 && !env_path_tainted()) + if (strcmp(nam, "PATH") == 0 && !env_path_tainted()) return str_new2(env); return str_taint(str_new2(env)); } @@ -1100,6 +1112,25 @@ env_indexes(argc, argv) return indexes; } +static VALUE +env_to_hash(obj) + VALUE obj; +{ + VALUE hash = hash_new(); + VALUE ary = env_keys(); + VALUE *ptr = RARRAY(ary)->ptr; + int len = RARRAY(ary)->len; + + while (len--) { + VALUE val = f_getenv(Qnil, *ptr); + if (!NIL_P(val)) { + hash_aset(hash, *ptr, val); + } + ptr++; + } + return hash; +} + void Init_Hash() { @@ -1121,6 +1152,7 @@ Init_Hash() rb_define_method(cHash,"freeze", hash_freeze, 0); rb_define_method(cHash,"frozen?",hash_frozen_p, 0); + rb_define_method(cHash,"to_hash", hash_to_hash, 0); rb_define_method(cHash,"to_a", hash_to_a, 0); rb_define_method(cHash,"to_s", hash_to_s, 0); rb_define_method(cHash,"inspect", hash_inspect, 0); @@ -1181,6 +1213,7 @@ Init_Hash() rb_define_singleton_method(envtbl,"has_value?", env_has_value, 1); rb_define_singleton_method(envtbl,"key?", env_has_key, 1); rb_define_singleton_method(envtbl,"value?", env_has_value, 1); + rb_define_singleton_method(envtbl,"to_hash", env_to_hash, 0); rb_define_global_const("ENV", envtbl); } diff --git a/intern.h b/intern.h index 2b87408ac7..af309fb3bc 100644 --- a/intern.h +++ b/intern.h @@ -187,6 +187,7 @@ VALUE rb_inspect _((VALUE)); VALUE obj_is_instance_of _((VALUE, VALUE)); VALUE obj_is_kind_of _((VALUE, VALUE)); VALUE obj_alloc _((VALUE)); +VALUE rb_convert_type _((VALUE,int,char*,char*)); VALUE rb_Integer _((VALUE)); VALUE rb_Float _((VALUE)); VALUE rb_String _((VALUE)); diff --git a/io.c b/io.c index 4350a9acab..b2acba401a 100644 --- a/io.c +++ b/io.c @@ -1172,11 +1172,7 @@ static VALUE io_get_io(io) VALUE io; { - if (TYPE(io) != T_FILE) { - io = rb_funcall(io, rb_intern("to_io"), 0, 0); - Check_Type(io, T_FILE); - } - return io; + return rb_convert_type(io, T_FILE, "IO", "to_io"); } #ifndef NT diff --git a/lib/telnet.rb b/lib/telnet.rb index e93c2aaa8e..44fda9e41a 100644 --- a/lib/telnet.rb +++ b/lib/telnet.rb @@ -4,54 +4,54 @@ # Wakou Aoyama # # == make new Telnet object -# host = Telnet.new({"Binmode" => TRUE, default: TRUE -# "Host" => "localhost", default: "localhost" -# "Output_log"] => "output_log", default: not output -# "Port" => 23, default: 23 -# "Prompt" => /[$%#>] $/, default: /[$%#>] $/ -# "Telnetmode"] => TRUE, default: TRUE -# "Timeout"] => 10} default: 10 +# host = Telnet.new("Binmode" => TRUE, default: TRUE +# "Host" => "localhost", default: "localhost" +# "Output_log" => "output_log", default: not output +# "Port" => 23, default: 23 +# "Prompt" => /[$%#>] $/, default: /[$%#>] $/ +# "Telnetmode" => TRUE, default: TRUE +# "Timeout" => 10) default: 10 # # if set "Telnetmode" option FALSE. not TELNET command interpretation. # # == wait for match # print host.waitfor(/match/) -# print host.waitfor({"Match" => /match/, -# "String" => "string", -# "Timeout" => secs}) +# print host.waitfor("Match" => /match/, +# "String" => "string", +# "Timeout" => secs) # if set "String" option. Match = Regexp.new(quote(string)) # # realtime output. of cource, set sync=TRUE or flush is necessary. # host.waitfor(/match/){|c| print c } -# host.waitfor({"Match" => /match/, -# "String" => "string", -# "Timeout" => secs}){|c| print c} +# host.waitfor("Match" => /match/, +# "String" => "string", +# "Timeout" => secs){|c| print c} # # == send string and wait prompt # print host.cmd("string") -# print host.cmd({"String" => "string", -# "Prompt" => /[$%#>] $//, -# "Timeout" => 10}) +# print host.cmd("String" => "string", +# "Prompt" => /[$%#>] $//, +# "Timeout" => 10) # # realtime output. of cource, set sync=TRUE or flush is necessary. # host.cmd("string"){|c| print c } -# host.cmd({"String" => "string", -# "Prompt" => /[$%#>] $//, -# "Timeout" => 10}){|c| print c } +# host.cmd("String" => "string", +# "Prompt" => /[$%#>] $//, +# "Timeout" => 10){|c| print c } # # == login # host.login("username", "password") -# host.login({"Name" => "username", -# "Password" => "password", -# "Prompt" => /[$%#>] $/, -# "Timeout" => 10}) +# host.login("Name" => "username", +# "Password" => "password", +# "Prompt" => /[$%#>] $/, +# "Timeout" => 10) # # and Telnet object has socket class methods # # == sample -# localhost = Telnet.new({"Host" => "localhost", -# "Timeout" => 10, -# "Prompt" => /[$%#>] $/}) +# localhost = Telnet.new("Host" => "localhost", +# "Timeout" => 10, +# "Prompt" => /[$%#>] $/) # localhost.login("username", "password") # print localhost.cmd("command") # localhost.close diff --git a/lib/tk.rb b/lib/tk.rb index 08a146b8be..8c361c03e5 100644 --- a/lib/tk.rb +++ b/lib/tk.rb @@ -48,8 +48,9 @@ module TkComm end def tk_split_list(str) + return [] if str == "" idx = str.index('{') - return tk_tcl2ruby(str) if not idx + return tk_tcl2ruby(str) unless idx list = tk_tcl2ruby(str[0,idx]) str = str[idx+1..-1] @@ -112,7 +113,8 @@ module TkComm end end def list(val) - tk_split_list(val) + p val + tk_split_list(val).to_a end def window(val) Tk_WINDOWS[val] @@ -260,7 +262,7 @@ module TkCore extend TkComm INTERP = TclTkIp.new - INTERP._eval("proc rb_out {args} { ruby [format \"TkCore.callback %%Q!%s!\" $args] }") + INTERP._invoke("proc", "rb_out", "args", "ruby [format \"TkCore.callback %%Q!%s!\" $args]") def TkCore.callback(arg) arg = Array(tk_split_list(arg)) @@ -271,36 +273,35 @@ module TkCore TclTkLib.mainloop end - def _get_eval_string(*args) - argstr = "" - args.each{|arg| - next if arg == None - if arg.kind_of?(Hash) - str = hash_kv(arg).join(" ") - elsif arg == nil - str = "" - elsif arg == false - str = "0" - elsif arg == true - str = "1" - elsif (arg.respond_to?(:to_eval)) - str = arg.to_eval() - else - str = arg.to_s() - end - argstr += " " if argstr != "" - argstr += '"' + str.gsub(/[][$"]/, '\\\\\&') + '"' #' - } - return argstr + def _get_eval_string(str) + return str if str == None + if str.kind_of?(Hash) + str = hash_kv(str).join(" ") + elsif str == nil + str = "" + elsif str == false + str = "0" + elsif str == true + str = "1" + elsif (str.respond_to?(:to_eval)) + str = str.to_eval() + else + str = str.to_s() + end + return str end def tk_call(*args) - argstr = _get_eval_string(*args) - - res = INTERP._eval(argstr) + print args.join(" "), "\n" if $DEBUG + args.filter {|x|_get_eval_string(x)} + args.delete!(None) + args.flatten! + args.compact! + res = INTERP._invoke(*args) if INTERP._return_value() != 0 fail RuntimeError, res, error_at end + print "==> ", res, "\n" if $DEBUG return res end end @@ -376,7 +377,8 @@ module Tk list(w) if args.size == 0 end def iconwindow(*args) - tk_call 'wm', 'iconwindow', path, *args + w = tk_call('wm', 'iconwindow', path, *args) + window(w) if args.size == 0 end def maxsize(*args) w = tk_call('wm', 'maxsize', path, *args) @@ -431,7 +433,8 @@ class TkVariable def initialize(val="") @id = Tk_VARIABLE_ID[0] Tk_VARIABLE_ID[0] = Tk_VARIABLE_ID[0].succ - INTERP._eval(format('global %s; set %s %s', @id, @id, _get_eval_string(val))) + s = '"' + _get_eval_string(val).gsub(/[][$"]/, '\\\\\&') + '"' #' + INTERP._eval(format('global %s; set %s %s', @id, @id, s)) end def id @@ -816,6 +819,8 @@ class TkObjectval, rb_intern(arg->s), 0); } static VALUE -fail_to_flo(val) +fail_to_type(arg) + struct arg_to *arg; +{ + TypeError("failed to convert %s into %s", + rb_class2name(CLASS_OF(arg->val)), arg->s); +} + +VALUE +rb_convert_type(val, type, tname, method) VALUE val; + int type; + char *tname, *method; { - TypeError("failed to convert %s into Float", rb_class2name(CLASS_OF(val))); + struct arg_to arg1, arg2; + + if (TYPE(val) == type) return val; + arg1.val = arg2.val = val; + arg1.s = method; + arg2.s = tname; + val = rb_rescue(to_type, &arg1, fail_to_type, &arg2); + Check_Type(val, type); + return val; } double big2dbl(); @@ -774,7 +797,7 @@ f_float(obj, arg) return float_new(big2dbl(arg)); default: - return rb_rescue(to_flo, arg, fail_to_flo, arg); + return rb_convert_type(arg, T_FLOAT, "Float", "to_f"); } } @@ -793,44 +816,23 @@ num2dbl(val) return RFLOAT(v)->value; } -static VALUE -to_s(obj) - VALUE obj; -{ - return rb_funcall(obj, rb_intern("to_s"), 0); -} - -static VALUE -fail_to_str(val) - VALUE val; -{ - TypeError("failed to convert %s into Sting", - rb_class2name(CLASS_OF(val))); -} - static VALUE f_string(obj, arg) VALUE obj, arg; { - return rb_rescue(to_s, arg, fail_to_str, arg); -} - -static VALUE -to_str(obj) - VALUE obj; -{ - return rb_funcall(obj, rb_intern("to_str"), 0); + return rb_convert_type(arg, T_STRING, "String", "to_s"); } char* -str2cstr(str) +str2cstr(str, len) VALUE str; + int *len; { if (NIL_P(str)) return NULL; if (TYPE(str) != T_STRING) { - str = rb_rescue(to_str, str, fail_to_str, str); - Check_Type(str, T_STRING); + str = rb_convert_type(str, T_STRING, "String", "to_str"); } + if (len) *len = RSTRING(str)->len; return RSTRING(str)->ptr; } diff --git a/random.c b/random.c index 7902658fbd..8d01a961b1 100644 --- a/random.c +++ b/random.c @@ -24,8 +24,12 @@ struct timeval { #endif #endif /* NT */ -static int first = 1; +#ifdef HAVE_STDLIB_H +# include +#endif + #ifdef HAVE_RANDOM +static int first = 1; static char state[256]; #endif @@ -43,7 +47,7 @@ f_srand(argc, argv, obj) struct timeval tv; gettimeofday(&tv, 0); - seed = tv.tv_usec; + seed = tv.tv_sec ^ tv.tv_usec; } else { seed = NUM2INT(seed); @@ -78,16 +82,12 @@ f_rand(obj, vmax) { int val, max; - if (first == 1) { - f_srand(0, 0, 0); - } - switch (TYPE(vmax)) { case T_BIGNUM: return big_rand(vmax); case T_FLOAT: - if (RFLOAT(vmax)->value > LONG_MAX || RFLOAT(vmax)->value < LONG_MIN) + if (RFLOAT(vmax)->value > INT_MAX || RFLOAT(vmax)->value < INT_MIN) return big_rand(dbl2big(RFLOAT(vmax)->value)); break; } @@ -96,9 +96,14 @@ f_rand(obj, vmax) if (max == 0) ArgError("rand(0)"); #ifdef HAVE_RANDOM - val = random() % max; + val = random(); +#else + val = rand(); +#endif +#ifdef RAND_MAX + val = val * (double)max / (double)RAND_MAX; #else - val = rand() % max; + val = (val>>8) % max; #endif if (val < 0) val = -val; diff --git a/ruby.h b/ruby.h index 409a859159..f73af1b72c 100644 --- a/ruby.h +++ b/ruby.h @@ -75,7 +75,7 @@ typedef unsigned short USHORT; # ifdef HAVE_LIMITS_H # include # else - /* assuming 32bit(2's compliment) LONG */ + /* assuming 32bit(2's compliment) long */ # define LONG_MAX 2147483647 # endif # endif @@ -176,8 +176,8 @@ INT num2int _((VALUE)); double num2dbl _((VALUE)); #define NUM2DBL(x) num2dbl((VALUE)(x)) -char *str2cstr _((VALUE)); -#define STR2CSTR(x) str2cstr((VALUE)(x)) +char *str2cstr _((VALUE,int*)); +#define STR2CSTR(x) str2cstr((VALUE)(x),0) #define NUM2CHR(x) (((TYPE(x) == T_STRING)&&(RSTRING(x)->len>=1))?\ RSTRING(x)->ptr[0]:(char)NUM2INT(x)) @@ -423,7 +423,6 @@ volatile voidfn Raise; volatile voidfn Fail; volatile voidfn Fatal; volatile voidfn Bug; -volatile voidfn WrongType; volatile voidfn rb_sys_fail; volatile voidfn rb_iter_break; volatile voidfn rb_exit; @@ -435,7 +434,6 @@ void Raise(); void Fail(); void Fatal(); void Bug(); -void WrongType(); void rb_sys_fail _((char *)); void rb_iter_break _((void)); void rb_exit _((int)); diff --git a/string.c b/string.c index 22f465f9de..83169f4192 100644 --- a/string.c +++ b/string.c @@ -106,12 +106,25 @@ str_new4(orig) } } +static VALUE +to_str(str) + VALUE str; +{ + return rb_convert_type(str, T_STRING, "String", "to_str"); +} + static void str_assign(str, str2) VALUE str, str2; { - if (NIL_P(str2) || str == str2) return; - if ((!RSTRING(str)->orig||FL_TEST(str, STR_NO_ORIG)) && RSTRING(str)->ptr) + if (str == str2) return; + if (NIL_P(str2)) { + RSTRING(str)->ptr = 0; + RSTRING(str)->len = 0; + RSTRING(str)->orig = 0; + return; + } + if ((!RSTRING(str)->orig||FL_TEST(str, STR_NO_ORIG))&&RSTRING(str)->ptr) free(RSTRING(str)->ptr); RSTRING(str)->ptr = RSTRING(str2)->ptr; RSTRING(str)->len = RSTRING(str2)->len; @@ -212,11 +225,7 @@ str_plus(str1, str2) { VALUE str3; -#if 0 - str2 = obj_as_string(str2); -#else - Check_Type(str2, T_STRING); -#endif + str2 = to_str(str2); str3 = str_new(0, RSTRING(str1)->len+RSTRING(str2)->len); memcpy(RSTRING(str3)->ptr, RSTRING(str1)->ptr, RSTRING(str1)->len); memcpy(RSTRING(str3)->ptr+RSTRING(str1)->len, RSTRING(str2)->ptr, RSTRING(str2)->len); @@ -437,12 +446,7 @@ static VALUE str_concat(str1, str2) VALUE str1, str2; { -#if 0 - str2 = obj_as_string(str2); -#else - if (NIL_P(str2)) return str1; - Check_Type(str2, T_STRING); -#endif + str2 = to_str(str2); str_cat(str1, RSTRING(str2)->ptr, RSTRING(str2)->len); return str1; } @@ -523,11 +527,7 @@ str_cmp_method(str1, str2) { int result; -#if 0 - str2 = obj_as_string(str2); -#else - Check_Type(str2, T_STRING); -#endif + str2 = to_str(str2); result = str_cmp(str1, str2); return INT2FIX(result); } @@ -767,7 +767,7 @@ str_upto(beg, end) { VALUE current; - Check_Type(end, T_STRING); + end = to_str(end); if (RTEST(rb_funcall(beg, '>', 1, end))) return Qnil; @@ -1117,8 +1117,7 @@ str_aset_method(argc, argv, str) if (rb_scan_args(argc, argv, "21", &arg1, &arg2, &arg3) == 3) { int beg, len; - Check_Type(arg3, T_STRING); - + arg3 = to_str(arg3); beg = NUM2INT(arg1); if (beg < 0) { beg = RSTRING(str)->len + beg; @@ -1203,8 +1202,7 @@ static VALUE str_replace_method(str, str2) VALUE str, str2; { - Check_Type(str2, T_STRING); - + str2 = to_str(str2); str_modify(str); str_resize(str, RSTRING(str2)->len); memcpy(RSTRING(str)->ptr, RSTRING(str2)->ptr, RSTRING(str2)->len); @@ -1352,8 +1350,7 @@ str_include(str, arg) return FALSE; } - Check_Type(arg, T_STRING); - i = str_index(str, arg, 0); + i = str_index(str, to_str(arg), 0); if (i == -1) return FALSE; return INT2FIX(i); @@ -1755,13 +1752,13 @@ tr_trans(str, src, repl, sflag) UCHAR *s, *send; str_modify(str); - Check_Type(src, T_STRING); + src = to_str(src); trsrc.p = RSTRING(src)->ptr; trsrc.pend = trsrc.p + RSTRING(src)->len; if (RSTRING(src)->len > 2 && RSTRING(src)->ptr[0] == '^') { cflag++; trsrc.p++; } - Check_Type(repl, T_STRING); + repl = to_str(repl); if (RSTRING(repl)->len == 0) return str_delete_bang(str, src); trrepl.p = RSTRING(repl)->ptr; trrepl.pend = trrepl.p + RSTRING(repl)->len; @@ -1884,13 +1881,13 @@ tr_setup_table(str, table) static VALUE str_delete_bang(str1, str2) - VALUE str1, *str2; + VALUE str1, str2; { UCHAR *s, *send, *t; UCHAR squeez[256]; int modify = 0; - Check_Type(str2, T_STRING); + str2 = to_str(str2); tr_setup_table(str2, squeez); str_modify(str1); @@ -1968,7 +1965,7 @@ str_squeeze_bang(argc, argv, str1) VALUE str2; if (rb_scan_args(argc, argv, "01", &str2) == 1) { - Check_Type(str2, T_STRING); + str2 = to_str(str2); } return tr_squeeze(str1, str2); } @@ -2145,7 +2142,7 @@ str_split(str, sep0) { VALUE sep; - Check_Type(str, T_STRING); + str = to_str(str); sep = str_new2(sep0); return str_split_method(1, &sep, str); } @@ -2180,7 +2177,7 @@ str_each_line(argc, argv, str) rb_yield(str); return Qnil; } - Check_Type(rs, T_STRING); + rs = to_str(rs); rslen = RSTRING(rs)->len; if (rslen == 0) { @@ -2293,7 +2290,7 @@ str_chomp_bang(argc, argv, str) } if (NIL_P(rs)) return Qnil; - Check_Type(rs, T_STRING); + rs = to_str(rs); rslen = RSTRING(rs)->len; if (rslen == 0) { while (len>0 && p[len-1] == '\n') { @@ -2490,7 +2487,7 @@ str_crypt(str, salt) { extern char *crypt(); - Check_Type(salt, T_STRING); + salt = to_str(salt); if (RSTRING(salt)->len < 2) ArgError("salt too short(need >2 bytes)"); return str_new2(crypt(RSTRING(str)->ptr, RSTRING(salt)->ptr)); diff --git a/variable.c b/variable.c index d676995450..099476c731 100644 --- a/variable.c +++ b/variable.c @@ -249,10 +249,7 @@ VALUE f_autoload(obj, klass, file) VALUE obj, klass, file; { - ID id = rb_to_id(klass); - - Check_Type(file, T_STRING); - rb_autoload_id(id, RSTRING(file)->ptr); + rb_autoload_id(rb_to_id(klass), STR2CSTR(file)); return Qnil; } -- cgit v1.2.3