summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--array.c3
-rw-r--r--error.c31
-rw-r--r--eval.c68
-rw-r--r--ext/gtk/extconf.rb2
-rw-r--r--lib/debug.rb7
-rw-r--r--lib/delegate.rb2
-rw-r--r--lib/tk.rb21
-rw-r--r--object.c3
-rw-r--r--parse.y3
-rw-r--r--sample/from.rb13
-rw-r--r--string.c7
-rw-r--r--struct.c1
-rw-r--r--time.c7
14 files changed, 137 insertions, 48 deletions
diff --git a/ChangeLog b/ChangeLog
index 9f90111d42..0012feeff3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+Thu Apr 30 01:08:35 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * lib/tk.rb: call 'unknown', if proc not defined.
+
+ * eval.c (handle_rescue): default rescue handles `Exceptional' not
+ only the instance of the `Exception's.
+
+ * eval.c (errinfo_setter): $! can be any `Throwable' object.
+
+ * time.c (time_gm_or_local): call time_gmtime or time_localtime.
+
+ * eval.c (f_raise): raises TypeError if the class which is not a
+ subclass of String is specified (checked in exc_new()).
+
+ * error.c (exc_new): need to check whether invalid class (not a
+ subclass of String) is specified.
+
Tue Apr 28 15:27:58 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* experimental release 1.1b9_16.
diff --git a/array.c b/array.c
index 651a2cbee4..529c936c22 100644
--- a/array.c
+++ b/array.c
@@ -640,7 +640,7 @@ ary_join(ary, sep)
default:
tmp = obj_as_string(tmp);
}
- if (!NIL_P(sep)) str_cat(result, RSTRING(sep)->ptr, RSTRING(sep)->len);
+ if (!NIL_P(sep)) str_concat(result, sep);
str_cat(result, RSTRING(tmp)->ptr, RSTRING(tmp)->len);
if (str_tainted(tmp)) str_taint(result);
}
@@ -658,7 +658,6 @@ ary_join_method(argc, argv, ary)
rb_scan_args(argc, argv, "01", &sep);
if (NIL_P(sep)) sep = OFS;
- if (!NIL_P(sep)) Check_Type(sep, T_STRING);
return ary_join(ary, sep);
}
diff --git a/error.c b/error.c
index a4e433a869..dcbec0b336 100644
--- a/error.c
+++ b/error.c
@@ -212,6 +212,7 @@ rb_check_type(x, t)
#include "errno.h"
extern VALUE cString;
+VALUE eThrowable, eExceptional;
VALUE eGlobalExit, eException;
VALUE eSystemExit, eInterrupt, eFatal;
VALUE eRuntimeError;
@@ -258,8 +259,11 @@ VALUE
exc_new3(etype, str)
VALUE etype, str;
{
- Check_Type(str, T_STRING);
- return exc_new(etype, RSTRING(str)->ptr, RSTRING(str)->len);
+ char *s;
+ int len;
+
+ s = str2cstr(str, &len);
+ return exc_new(etype, s, len);
}
static VALUE
@@ -281,6 +285,23 @@ exc_s_new(argc, argv, etype)
}
static VALUE
+exc_new_method(self, str)
+ VALUE self, str;
+{
+ VALUE etype;
+ char *s;
+ int len;
+
+ if (self == str) return self;
+ etype = CLASS_OF(self);
+ while (FL_TEST(etype, FL_SINGLETON)) {
+ etype = RCLASS(etype)->super;
+ }
+ s = str2cstr(str, &len);
+ return exc_new(etype, s, len);
+}
+
+static VALUE
exc_inspect(exc)
VALUE exc;
{
@@ -351,15 +372,21 @@ static void init_syserr();
void
Init_Exception()
{
+ eThrowable = rb_define_module("Throwable");
eGlobalExit = rb_define_class("GlobalExit", cString);
+ rb_include_module(eGlobalExit, eThrowable);
rb_define_singleton_method(eGlobalExit, "new", exc_s_new, -1);
+ rb_define_method(eGlobalExit, "new", exc_new_method, 1);
rb_define_method(eGlobalExit, "inspect", exc_inspect, 0);
eSystemExit = rb_define_class("SystemExit", eGlobalExit);
eFatal = rb_define_class("fatal", eGlobalExit);
eInterrupt = rb_define_class("Interrupt", eGlobalExit);
+ eExceptional = rb_define_module("Exceptional");
+ rb_include_module(eExceptional, eThrowable);
eException = rb_define_class("Exception", eGlobalExit);
+ rb_include_module(eException, eExceptional);
eSyntaxError = rb_define_class("SyntaxError", eException);
eTypeError = rb_define_class("TypeError", eException);
eArgError = rb_define_class("ArgumentError", eException);
diff --git a/eval.c b/eval.c
index 131acd5005..7184f10173 100644
--- a/eval.c
+++ b/eval.c
@@ -362,7 +362,8 @@ extern int nerrs;
extern VALUE mKernel;
extern VALUE cModule;
extern VALUE eFatal;
-extern VALUE eGlobalExit;
+extern VALUE eThrowable;
+extern VALUE eExceptional;
extern VALUE eInterrupt;
extern VALUE eSystemExit;
extern VALUE eException;
@@ -722,6 +723,7 @@ static void
error_print()
{
VALUE eclass;
+ VALUE einfo;
if (NIL_P(errinfo)) return;
@@ -735,36 +737,37 @@ error_print()
}
eclass = CLASS_OF(errinfo);
- if (eclass == eRuntimeError && RSTRING(errinfo)->len == 0) {
+ einfo = obj_as_string(errinfo);
+ if (eclass == eRuntimeError && RSTRING(einfo)->len == 0) {
fprintf(stderr, ": unhandled exception\n");
}
else {
VALUE epath;
epath = rb_class_path(eclass);
- if (RSTRING(errinfo)->len == 0) {
+ if (RSTRING(einfo)->len == 0) {
fprintf(stderr, ": ");
fwrite(RSTRING(epath)->ptr, 1, RSTRING(epath)->len, stderr);
putc('\n', stderr);
}
else {
- unsigned char *tail = 0;
- int len = RSTRING(errinfo)->len;
+ UCHAR *tail = 0;
+ int len = RSTRING(einfo)->len;
if (RSTRING(epath)->ptr[0] == '#') epath = 0;
- if (tail = strchr(RSTRING(errinfo)->ptr, '\n')) {
- len = tail - RSTRING(errinfo)->ptr;
+ if (tail = strchr(RSTRING(einfo)->ptr, '\n')) {
+ len = tail - RSTRING(einfo)->ptr;
tail++; /* skip newline */
}
fprintf(stderr, ": ");
- fwrite(RSTRING(errinfo)->ptr, 1, len, stderr);
+ fwrite(RSTRING(einfo)->ptr, 1, len, stderr);
if (epath) {
fprintf(stderr, " (");
fwrite(RSTRING(epath)->ptr, 1, RSTRING(epath)->len, stderr);
fprintf(stderr, ")\n");
}
if (tail) {
- fwrite(tail, 1, RSTRING(errinfo)->len-len-1, stderr);
+ fwrite(tail, 1, RSTRING(einfo)->len-len-1, stderr);
putc('\n', stderr);
}
}
@@ -982,9 +985,10 @@ static void
compile_error(at)
char *at;
{
- VALUE mesg;
+ char *mesg;
+ int len;
- mesg = errinfo;
+ mesg = str2cstr(errinfo, &len);
nerrs = 0;
errinfo = exc_new2(eSyntaxError, "compile error");
if (at) {
@@ -992,7 +996,7 @@ compile_error(at)
str_cat(errinfo, at, strlen(at));
}
str_cat(errinfo, "\n", 1);
- str_cat(errinfo, RSTRING(mesg)->ptr, RSTRING(mesg)->len);
+ str_cat(errinfo, mesg, len);
rb_raise(errinfo);
}
@@ -1378,7 +1382,7 @@ is_defined(self, node, buf)
case NODE_LVAR:
return "local-variable";
case NODE_DVAR:
- return "local-variable(ephemeral)";
+ return "local-variable(in-block)";
case NODE_GVAR:
if (rb_gvar_defined(node->nd_entry)) {
@@ -2704,13 +2708,15 @@ rb_longjmp(tag, mesg, at)
}
if (!NIL_P(mesg)) {
- if (obj_is_kind_of(mesg, eGlobalExit)) {
+ if (obj_is_kind_of(mesg, eThrowable)) {
errinfo = mesg;
}
else {
errinfo = exc_new3(eRuntimeError, mesg);
}
- str_freeze(errinfo);
+ if (TYPE(errinfo) == T_STRING) {
+ str_freeze(errinfo);
+ }
}
trap_restore_mask();
@@ -2759,7 +2765,7 @@ f_raise(argc, argv)
case 2:
case 3:
etype = arg1;
- if (obj_is_kind_of(etype, eGlobalExit)) {
+ if (obj_is_kind_of(etype, eThrowable)) {
etype = CLASS_OF(etype);
}
else {
@@ -2770,9 +2776,12 @@ f_raise(argc, argv)
}
if (!NIL_P(mesg)) {
- Check_Type(mesg, T_STRING);
- if (n == 2 || !obj_is_kind_of(mesg, eException)) {
- mesg = exc_new3(etype, mesg);
+ if (n >= 2 || !obj_is_kind_of(mesg, eThrowable)) {
+ mesg = rb_funcall(etype, rb_intern("new"), 1, mesg);
+ }
+ if (!obj_is_kind_of(mesg, eThrowable)) {
+ TypeError("should be Throwable, %s given",
+ rb_class2name(CLASS_OF(mesg)));
}
}
@@ -3042,7 +3051,7 @@ handle_rescue(self, node)
TMP_PROTECT;
if (!node->nd_args) {
- return obj_is_kind_of(errinfo, eException);
+ return obj_is_kind_of(errinfo, eExceptional);
}
PUSH_ITER(ITER_NOT);
@@ -3071,7 +3080,7 @@ rb_rescue(b_proc, data1, r_proc, data2)
retry_entry:
result = (*b_proc)(data1);
}
- else if (state == TAG_RAISE && obj_is_kind_of(errinfo, eException)) {
+ else if (state == TAG_RAISE && obj_is_kind_of(errinfo, eExceptional)) {
if (r_proc) {
PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
@@ -3838,7 +3847,7 @@ eval(self, src, scope, file, line)
if (sourceline > 1) {
err = RARRAY(errat)->ptr[0];
str_cat(err, ": ", 2);
- str_cat(err, RSTRING(errinfo)->ptr, RSTRING(errinfo)->len);
+ str_concat(err, errinfo);
}
else {
err = str_dup(errinfo);
@@ -4488,6 +4497,19 @@ errat_setter(val, id, var)
*var = check_errat(val);
}
+static void
+errinfo_setter(val, id, var)
+ VALUE val;
+ ID id;
+ VALUE *var;
+{
+ if (!obj_is_kind_of(val, eThrowable)) {
+ TypeError("$! should be Throwable, %s given",
+ rb_class2name(CLASS_OF(val)));
+ }
+ *var = val;
+}
+
VALUE f_global_variables();
VALUE f_instance_variables();
@@ -4595,7 +4617,7 @@ Init_eval()
rb_global_variable((VALUE*)&the_dyna_vars);
rb_define_hooked_variable("$@", &errat, 0, errat_setter);
- rb_define_hooked_variable("$!", &errinfo, 0, rb_str_setter);
+ rb_define_hooked_variable("$!", &errinfo, 0, errinfo_setter);
rb_define_global_function("eval", f_eval, -1);
rb_define_global_function("iterator?", f_iterator_p, 0);
diff --git a/ext/gtk/extconf.rb b/ext/gtk/extconf.rb
index a30f050e66..5839fac1ce 100644
--- a/ext/gtk/extconf.rb
+++ b/ext/gtk/extconf.rb
@@ -2,7 +2,7 @@ require "mkmf"
# may need to be changed
$LDFLAGS="-L/usr/X11R6/lib -L/usr/local/lib"
-$CFLAGS=`gtk-config --cflags`
+$CFLAGS=`gtk-config --cflags`.chomp!
have_library("X11", "XOpenDisplay")
have_library("Xext", "XShmQueryVersion")
diff --git a/lib/debug.rb b/lib/debug.rb
index 432c7b4d19..2e3a29aa9e 100644
--- a/lib/debug.rb
+++ b/lib/debug.rb
@@ -11,6 +11,8 @@ class DEBUGGER__
@scripts = {}
end
+ DEBUG_LAST_CMD = []
+
def interrupt
@stop_next = 1
end
@@ -40,6 +42,11 @@ class DEBUGGER__
STDOUT.flush
while input = STDIN.gets
input.chop!
+ if input == ""
+ input = DEBUG_LAST_CMD[0]
+ else
+ DEBUG_LAST_CMD[0] = input
+ end
case input
when /^b(reak)?\s+(([^:\n]+:)?.+)/
pos = $2
diff --git a/lib/delegate.rb b/lib/delegate.rb
index c73a3bd8a0..bc6f876212 100644
--- a/lib/delegate.rb
+++ b/lib/delegate.rb
@@ -7,7 +7,7 @@
#
# Usage:
# foo = Object.new
-# foo = SimpleDelegator.new(foo)
+# foo2 = SimpleDelegator.new(foo)
# foo.hash == foo2.hash # => true
class Delegator
diff --git a/lib/tk.rb b/lib/tk.rb
index 8c361c03e5..213fc54de7 100644
--- a/lib/tk.rb
+++ b/lib/tk.rb
@@ -113,7 +113,6 @@ module TkComm
end
end
def list(val)
- p val
tk_split_list(val).to_a
end
def window(val)
@@ -274,7 +273,7 @@ module TkCore
end
def _get_eval_string(str)
- return str if str == None
+ return nil if str == None
if str.kind_of?(Hash)
str = hash_kv(str).join(" ")
elsif str == nil
@@ -294,10 +293,20 @@ module TkCore
def tk_call(*args)
print args.join(" "), "\n" if $DEBUG
args.filter {|x|_get_eval_string(x)}
- args.delete!(None)
- args.flatten!
args.compact!
- res = INTERP._invoke(*args)
+ args.flatten!
+ begin
+ res = INTERP._invoke(*args)
+ rescue NameError
+ err = $!
+ begin
+ args.unshift "unknown"
+ res = INTERP._invoke(*args)
+ rescue
+ raise unless /^invalid command/ =~ $!
+ raise err
+ end
+ end
if INTERP._return_value() != 0
fail RuntimeError, res, error_at
end
@@ -819,8 +828,6 @@ class TkObject<TkKernel
if (args.length == 1)
configure id.id2name, args[0]
else
- p caller
- p id.id2name
$@ = error_at
super
end
diff --git a/object.c b/object.c
index b04752bcd4..f57a3cebda 100644
--- a/object.c
+++ b/object.c
@@ -526,7 +526,8 @@ mod_cmp(mod, arg)
return INT2FIX(1);
}
-VALUE module_s_new()
+VALUE
+module_s_new()
{
VALUE mod = module_new();
diff --git a/parse.y b/parse.y
index 244d87f33a..734d1321c1 100644
--- a/parse.y
+++ b/parse.y
@@ -2366,8 +2366,7 @@ retry:
case '<':
c = nextc();
if (c == '<' &&
- lex_state != EXPR_END
- && lex_state != EXPR_CLASS &&
+ lex_state != EXPR_END && lex_state != EXPR_CLASS &&
(lex_state != EXPR_ARG || space_seen)) {
int c2 = nextc();
if (!isspace(c2) && (strchr("\"'`", c2) || is_identchar(c2))) {
diff --git a/sample/from.rb b/sample/from.rb
index 0a83f081f1..98fc54799d 100644
--- a/sample/from.rb
+++ b/sample/from.rb
@@ -30,16 +30,19 @@ if ARGV[0] == '-w'
end
if ARGV.length == 0
- user = ENV['USER']
+ file = ENV['MAIL']
+ user = ENV['USER'] || ENV['USERNAME'] || ENV['LOGNAME']
else
file = user = ARGV[0]
ARGV.clear
end
-[ENV['SPOOLDIR'], '/usr/spool', '/var/spool', '/usr', '/var'].each do |m|
- if File.exist? f = "#{m}/mail/#{user}"
- file = f
- break
+if file == nil or !File.exist? file
+ [ENV['SPOOLDIR'], '/usr/spool', '/var/spool', '/usr', '/var'].each do |m|
+ if File.exist? f = "#{m}/mail/#{user}"
+ file = f
+ break
+ end
end
end
diff --git a/string.c b/string.c
index 83169f4192..cedf53acee 100644
--- a/string.c
+++ b/string.c
@@ -171,7 +171,10 @@ VALUE
str_dup(str)
VALUE str;
{
- VALUE s = str_new(RSTRING(str)->ptr, RSTRING(str)->len);
+ VALUE s;
+
+ str = to_str(str);
+ s = str_new(RSTRING(str)->ptr, RSTRING(str)->len);
if (str_tainted(str)) s = str_taint(s);
if (RSTRING(str)->orig && FL_TEST(str, STR_NO_ORIG))
RSTRING(s)->orig = RSTRING(str)->orig;
@@ -442,7 +445,7 @@ str_cat(str, ptr, len)
return str;
}
-static VALUE
+VALUE
str_concat(str1, str2)
VALUE str1, str2;
{
diff --git a/struct.c b/struct.c
index b6a19e14bb..6c581f4e0c 100644
--- a/struct.c
+++ b/struct.c
@@ -310,7 +310,6 @@ struct_inspect(s)
str_cat(str, p, strlen(p));
str_cat(str, "=", 1);
str2 = rb_inspect(RSTRUCT(s)->ptr[i]);
- str2 = obj_as_string(str2);
str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);
}
str_cat(str, ">", 1);
diff --git a/time.c b/time.c
index dbeafb4e55..5cb4087714 100644
--- a/time.c
+++ b/time.c
@@ -232,6 +232,8 @@ time_arg(argc, argv, args)
ArgError("argument out of range");
}
+static VALUE time_gmtime _((VALUE));
+static VALUE time_localtime _((VALUE));
static VALUE
time_gm_or_local(argc, argv, gm_or_local, klass)
int argc;
@@ -245,6 +247,7 @@ time_gm_or_local(argc, argv, gm_or_local, klass)
time_t guess, t;
int diff;
struct tm *(*fn)();
+ VALUE time;
fn = (gm_or_local) ? gmtime : localtime;
time_arg(argc, argv, args);
@@ -272,7 +275,9 @@ time_gm_or_local(argc, argv, gm_or_local, klass)
guess += (args[4] - tm->tm_min) * 60;
guess += args[5] - tm->tm_sec;
- return time_new_internal(klass, guess, 0);
+ time = time_new_internal(klass, guess, 0);
+ if (gm_or_local) return time_gmtime(time);
+ return time_localtime(time);
error:
ArgError("gmtime/localtime error");