summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog18
-rw-r--r--array.c26
-rw-r--r--dir.c8
-rw-r--r--eval.c5
-rw-r--r--ext/gtk/gtk.c40
-rw-r--r--ext/gtk/test2.rb4
-rw-r--r--ext/tcltklib/tcltklib.c21
-rw-r--r--file.c58
-rw-r--r--hash.c55
-rw-r--r--intern.h1
-rw-r--r--io.c6
-rw-r--r--lib/telnet.rb52
-rw-r--r--lib/tk.rb79
-rw-r--r--object.c66
-rw-r--r--random.c23
-rw-r--r--ruby.h8
-rw-r--r--string.c65
-rw-r--r--variable.c5
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 <matz@netlab.co.jp>
+
+ * 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 <maebashi@iij.ad.jp>
+
+ * 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 <matz@netlab.co.jp>
+
+ * random.c (f_rand): do not call srand() implicitly.
+
Fri Apr 24 14:35:45 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
+ * 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; i<RARRAY(ary1)->len; 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; i<RARRAY(ary1)->len; 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 <wakou@fsinet.or.jp>
#
# == 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 TkObject<TkKernel
if (args.length == 1)
configure id.id2name, args[0]
else
+ p caller
+ p id.id2name
$@ = error_at
super
end
@@ -1139,11 +1144,17 @@ class TkListbox<TkTextWin
tk_call 'listbox', path
end
+ def activate(y)
+ tk_send 'activate', y
+ end
def curselection
- tk_send 'curselection'
+ list(tk_send('curselection'))
end
def nearest(y)
- tk_send 'nearest', y
+ tk_send('nearest', y).to_i
+ end
+ def size(y)
+ tk_send('size').to_i
end
def selection_anchor(index)
tk_send 'selection', 'anchor', index
@@ -1158,10 +1169,12 @@ class TkListbox<TkTextWin
tk_send 'selection', 'set', first, last
end
def xview(cmd, index, *more)
- tk_send 'xview', cmd, index, *more
+ v = tk_send('xview', cmd, index, *more)
+ v.to_i if more.size == 0
end
def yview(cmd, index, *more)
- tk_send 'yview', cmd, index, *more
+ v = tk_send('yview', cmd, index, *more)
+ v.to_i if more.size == 0
end
end
diff --git a/object.c b/object.c
index bdf1373c4f..b04752bcd4 100644
--- a/object.c
+++ b/object.c
@@ -743,18 +743,41 @@ rb_Integer(val)
return f_integer(Qnil, val);
}
-static VALUE
-to_flo(val)
+struct arg_to {
VALUE val;
+ char *s;
+};
+
+static VALUE
+to_type(arg)
+ struct arg_to *arg;
{
- return rb_funcall(val, rb_intern("to_f"), 0);
+ return rb_funcall(arg->val, 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");
}
}
@@ -794,43 +817,22 @@ num2dbl(val)
}
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 <stdlib.h>
+#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 <limits.h>
# 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;
}