summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-05-06 03:09:03 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-05-06 03:09:03 +0000
commit6b7b84edc7168786408b0757e2eb53728d1b71a6 (patch)
tree299c41408ef82854a829327d1f8d5c4cc8cf6a8c
parent53118356b53259b456aabc11fb1212d965251fc4 (diff)
new exception model
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/v1_1r@202 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog22
-rw-r--r--Makefile.in2
-rw-r--r--error.c130
-rw-r--r--eval.c180
-rw-r--r--intern.h1
-rw-r--r--lib/pstore.rb11
-rw-r--r--lib/weakref.rb3
-rw-r--r--object.c2
-rw-r--r--re.c34
-rw-r--r--re.h2
-rw-r--r--ruby.c5
-rw-r--r--sample/test.rb2
-rw-r--r--string.c44
13 files changed, 264 insertions, 174 deletions
diff --git a/ChangeLog b/ChangeLog
index a1352d4870..e195ac095d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,27 @@
+Wed May 6 01:37:39 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * eval.c: remove global variable `errat'.
+
+ * eval.c (rb_longjmp): embed error position information in the
+ exception object.
+
+Sat May 2 12:20:02 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * re.c (reg_search): supports reverse search.
+
+ * string.c (str_index_method): does update $~ etc.
+
+ * eval.c (f_load): needed to clear the_dyna_vars.
+
+ * eval.c (dyna_var_asgn): do not push dyna_var, which is id == 0.
+
+ * error.c (Init_Exception): NotImplementError is no longer
+ StandardError, which is not handled by default rescue.
+
Fri May 1 00:35:51 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
+ * ruby.c (proc_options): `-d' turns on verbose flag too.
+
* error.c (exception): last argument may be the superclass of the
defining exception(s).
diff --git a/Makefile.in b/Makefile.in
index 64ac30fef4..cbf1eeec54 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -199,7 +199,7 @@ process.o: process.c ruby.h config.h defines.h intern.h sig.h st.h
random.o: random.c ruby.h config.h defines.h intern.h
range.o: range.c ruby.h config.h defines.h intern.h
re.o: re.c ruby.h config.h defines.h intern.h re.h regex.h
-ruby.o: ruby.c ruby.h config.h defines.h intern.h re.h regex.h dln.h
+ruby.o: ruby.c ruby.h config.h defines.h intern.h dln.h
signal.o: signal.c ruby.h config.h defines.h intern.h sig.h
sprintf.o: sprintf.c ruby.h config.h defines.h intern.h
st.o: st.c config.h st.h
diff --git a/error.c b/error.c
index f54fbc3b41..ae7a713578 100644
--- a/error.c
+++ b/error.c
@@ -214,7 +214,6 @@ rb_check_type(x, t)
extern VALUE cString;
VALUE eException;
VALUE eSystemExit, eInterrupt, eFatal;
-VALUE eDefaultRescue;
VALUE eStandardError;
VALUE eRuntimeError;
VALUE eSyntaxError;
@@ -222,9 +221,9 @@ VALUE eTypeError;
VALUE eArgError;
VALUE eNameError;
VALUE eIndexError;
-VALUE eNotImpError;
VALUE eLoadError;
VALUE eSecurityError;
+VALUE eNotImpError;
VALUE eSystemCallError;
VALUE mErrno;
@@ -235,17 +234,10 @@ exc_new(etype, ptr, len)
char *ptr;
UINT len;
{
- NEWOBJ(exc, struct RString);
- OBJSETUP(exc, etype, T_STRING);
+ VALUE exc = obj_alloc(etype);
- exc->len = len;
- exc->orig = 0;
- exc->ptr = ALLOC_N(char,len+1);
- if (ptr) {
- memcpy(exc->ptr, ptr, len);
- }
- exc->ptr[len] = '\0';
- return (VALUE)exc;
+ rb_iv_set(exc, "mesg", str_new(ptr, len));
+ return exc;
}
VALUE
@@ -268,38 +260,49 @@ exc_new3(etype, str)
}
static VALUE
-exc_s_new(argc, argv, etype)
+exc_initialize(argc, argv, exc)
int argc;
VALUE *argv;
- VALUE etype;
+ VALUE exc;
{
- VALUE arg, exc;
+ VALUE mesg;
- if (rb_scan_args(argc, argv, "01", &arg) == 0) {
- exc = exc_new(etype, 0, 0);
+ rb_scan_args(argc, argv, "01", &mesg);
+ if (NIL_P(mesg)) {
+ mesg = str_new(0, 0);
}
else {
- exc = exc_new3(etype, obj_as_string(arg));
+ STR2CSTR(mesg); /* ensure mesg can be converted to String */
}
- obj_call_init(exc);
+ rb_iv_set(exc, "mesg", mesg);
+
return exc;
}
static VALUE
-exc_new_method(self, str)
- VALUE self, str;
+exc_new_method(argc, argv, self)
+ int argc;
+ VALUE *argv;
+ VALUE self;
{
- VALUE etype;
- char *s;
- int len;
+ VALUE etype, exc;
- if (self == str) return self;
+ if (argc == 1 && self == argv[0]) 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);
+ exc = obj_alloc(etype);
+ obj_call_init(exc);
+
+ return exc;
+}
+
+static VALUE
+exc_to_s(exc)
+ VALUE exc;
+{
+ return rb_iv_get(exc, "mesg");
}
static VALUE
@@ -309,51 +312,93 @@ exc_inspect(exc)
VALUE str, klass;
klass = CLASS_OF(exc);
+ exc = obj_as_string(exc);
if (RSTRING(exc)->len == 0) {
return str_dup(rb_class_path(klass));
}
str = str_new2("#<");
klass = rb_class_path(klass);
- str_cat(str, RSTRING(klass)->ptr, RSTRING(klass)->len);
+ str_concat(str, klass);
str_cat(str, ":", 1);
- str_cat(str, RSTRING(exc)->ptr, RSTRING(exc)->len);
+ str_concat(str, exc);
str_cat(str, ">", 1);
return str;
}
static VALUE
+exc_backtrace(exc)
+ VALUE exc;
+{
+ return rb_iv_get(exc, "bt");
+}
+
+static VALUE
+check_backtrace(bt)
+ VALUE bt;
+{
+ int i;
+ static char *err = "backtrace must be Array of String";
+
+ if (!NIL_P(bt)) {
+ int t = TYPE(bt);
+
+ if (t == T_STRING) return ary_new3(1, bt);
+ if (t != T_ARRAY) {
+ TypeError(err);
+ }
+ for (i=0;i<RARRAY(bt)->len;i++) {
+ if (TYPE(RARRAY(bt)->ptr[i]) != T_STRING) {
+ TypeError(err);
+ }
+ }
+ }
+ return bt;
+}
+
+static VALUE
+exc_set_backtrace(exc, bt)
+ VALUE exc;
+{
+ return rb_iv_set(exc, "bt", check_backtrace(bt));
+}
+
+static VALUE
exception(argc, argv)
int argc;
VALUE *argv;
{
void ArgError();
- VALUE etype = eStandardError;
VALUE v = Qnil;
+ VALUE etype = eStandardError;
int i;
ID id;
if (argc == 0) {
ArgError("wrong # of arguments");
}
+ Warn("Exception() is now obsolete");
if (TYPE(argv[argc-1]) == T_CLASS) {
etype = argv[argc-1];
- argc--; argv++;
+ argc--;
+ if (!rb_funcall(etype, '<', 1, eException)) {
+ TypeError("exception should be subclass of Exception");
+ }
}
for (i=0; i<argc; i++) { /* argument check */
id = rb_to_id(argv[i]);
+ if (!rb_is_const_id(id)) {
+ ArgError("identifier `%s' needs to be constant", rb_id2name(id));
+ }
if (!rb_id2name(id)) {
ArgError("argument needs to be symbol or string");
}
- if (!rb_is_const_id(id)) {
- ArgError("identifier %s needs to be constant", rb_id2name(id));
- }
}
for (i=0; i<argc; i++) {
v = rb_define_class_under(the_class,
rb_id2name(rb_to_id(argv[i])),
- etype);
+ eStandardError);
}
return v;
}
@@ -380,28 +425,31 @@ static void init_syserr();
void
Init_Exception()
{
- eException = rb_define_class("Exception", cString);
- rb_define_singleton_method(eException, "new", exc_s_new, -1);
- rb_define_method(eException, "new", exc_new_method, 1);
+ eException = rb_define_class("Exception", cObject);
+ rb_define_method(eException, "new", exc_new_method, -1);
+ rb_define_method(eException, "initialize", exc_initialize, -1);
+ rb_define_method(eException, "to_s", exc_to_s, 0);
+ rb_define_method(eException, "to_str", exc_to_s, 0);
+ rb_define_method(eException, "message", exc_to_s, 0);
rb_define_method(eException, "inspect", exc_inspect, 0);
+ rb_define_method(eException, "backtrace", exc_backtrace, 0);
+ rb_define_private_method(eException, "set_backtrace", exc_set_backtrace, 1);
eSystemExit = rb_define_class("SystemExit", eException);
eFatal = rb_define_class("fatal", eException);
eInterrupt = rb_define_class("Interrupt", eException);
- eDefaultRescue = rb_define_module("DefaultRescue");
eStandardError = rb_define_class("StandardError", eException);
- rb_include_module(eStandardError, eDefaultRescue);
eSyntaxError = rb_define_class("SyntaxError", eStandardError);
eTypeError = rb_define_class("TypeError", eStandardError);
eArgError = rb_define_class("ArgumentError", eStandardError);
eNameError = rb_define_class("NameError", eStandardError);
eIndexError = rb_define_class("IndexError", eStandardError);
- eNotImpError = rb_define_class("NotImplementError", eStandardError);
eLoadError = rb_define_class("LoadError", eStandardError);
eRuntimeError = rb_define_class("RuntimeError", eStandardError);
eSecurityError = rb_define_class("SecurityError", eStandardError);
+ eNotImpError = rb_define_class("NotImplementError", eException);
init_syserr();
diff --git a/eval.c b/eval.c
index b0b929925a..c383a813e8 100644
--- a/eval.c
+++ b/eval.c
@@ -354,7 +354,7 @@ rb_attr(klass, id, read, write, ex)
}
static ID init, eqq, each, aref, aset, match;
-VALUE errinfo = Qnil, errat = Qnil;
+VALUE errinfo = Qnil;
extern NODE *eval_tree0;
extern NODE *eval_tree;
extern int nerrs;
@@ -362,7 +362,6 @@ extern int nerrs;
extern VALUE mKernel;
extern VALUE cModule;
extern VALUE eFatal;
-extern VALUE eDefaultRescue;
extern VALUE eStandardError;
extern VALUE eInterrupt;
extern VALUE eSystemExit;
@@ -453,15 +452,15 @@ new_dvar(id, value)
{
NEWOBJ(vars, struct RVarmap);
OBJSETUP(vars, 0, T_VARMAP);
+ vars->id = id;
+ vars->val = value;
+ vars->next = the_dyna_vars;
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;
}
@@ -504,12 +503,14 @@ dyna_var_asgn(id, value)
{
struct RVarmap *vars = the_dyna_vars;
- while (vars) {
- if (vars->id == id) {
- vars->val = value;
- return value;
+ if (id) {
+ while (vars) {
+ if (vars->id == id) {
+ vars->val = value;
+ return value;
+ }
+ vars = vars->next;
}
- vars = vars->next;
}
new_dvar(id, value);
return value;
@@ -719,14 +720,31 @@ error_pos()
}
}
+static VALUE
+get_backtrace(info)
+ VALUE info;
+{
+ if (NIL_P(info)) return Qnil;
+ return rb_funcall(info, rb_intern("backtrace"), 0);
+}
+
+static void
+set_backtrace(info, bt)
+ VALUE info, bt;
+{
+ rb_funcall(info, rb_intern("set_backtrace"), 1, bt);
+}
+
static void
error_print()
{
+ VALUE errat;
VALUE eclass;
VALUE einfo;
if (NIL_P(errinfo)) return;
+ errat = get_backtrace(errinfo);
if (!NIL_P(errat)) {
VALUE mesg = RARRAY(errat)->ptr[0];
@@ -909,7 +927,6 @@ ruby_run()
if (nerrs > 0) exit(nerrs);
init_stack();
- errat = Qnil; /* clear for execution */
PUSH_TAG(PROT_NONE);
PUSH_ITER(ITER_NOT);
@@ -985,19 +1002,20 @@ static void
compile_error(at)
char *at;
{
+ VALUE str;
char *mesg;
int len;
mesg = str2cstr(errinfo, &len);
nerrs = 0;
- errinfo = exc_new2(eSyntaxError, "compile error");
+ str = str_new2("compile error");
if (at) {
- str_cat(errinfo, " in ", 4);
- str_cat(errinfo, at, strlen(at));
+ str_cat(str, " in ", 4);
+ str_cat(str, at, strlen(at));
}
- str_cat(errinfo, "\n", 1);
- str_cat(errinfo, mesg, len);
- rb_raise(errinfo);
+ str_cat(str, "\n", 1);
+ str_cat(str, mesg, len);
+ rb_raise(exc_new3(eSyntaxError, str));
}
VALUE
@@ -1797,7 +1815,7 @@ rb_eval(self, node)
case NODE_RESCUE:
retry_entry:
{
- volatile VALUE e_info = errinfo, e_at = errat;
+ volatile VALUE e_info = errinfo;
PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
@@ -1817,7 +1835,6 @@ rb_eval(self, node)
POP_TAG();
if (state == 0) {
errinfo = e_info;
- errat = e_at;
}
else if (state == TAG_RETRY) {
state = 0;
@@ -2664,36 +2681,25 @@ static volatile voidfn rb_longjmp;
static VALUE make_backtrace _((void));
-static VALUE
-check_errat(val)
- VALUE val;
+static void
+rb_longjmp(tag, mesg)
+ int tag;
+ VALUE mesg;
{
- int i;
- static char *err = "value of $@ must be Array of String";
+ VALUE at;
- if (!NIL_P(val)) {
- int t = TYPE(val);
-
- if (t == T_STRING) return ary_new3(1, val);
- if (t != T_ARRAY) {
- TypeError(err);
- }
- for (i=0;i<RARRAY(val)->len;i++) {
- if (TYPE(RARRAY(val)->ptr[i]) != T_STRING) {
- TypeError(err);
- }
- }
+ if (NIL_P(mesg)) mesg = errinfo;
+ if (NIL_P(mesg)) {
+ mesg = exc_new(eRuntimeError, 0, 0);
}
- return val;
-}
-static void
-rb_longjmp(tag, mesg, at)
- int tag;
- VALUE mesg, at;
-{
- if (NIL_P(errinfo) && NIL_P(mesg)) {
- errinfo = exc_new(eRuntimeError, 0, 0);
+ at = get_backtrace(mesg);
+ if (NIL_P(at) && sourcefile && !NIL_P(mesg)) {
+ at = make_backtrace();
+ set_backtrace(mesg, at);
+ }
+ if (!NIL_P(mesg)) {
+ errinfo = mesg;
}
if (debug && !NIL_P(errinfo)) {
@@ -2701,16 +2707,6 @@ rb_longjmp(tag, mesg, at)
rb_class2name(CLASS_OF(errinfo)),
sourcefile, sourceline);
}
- if (!NIL_P(at)) {
- errat = check_errat(at);
- }
- else if (sourcefile && (NIL_P(errat) || !NIL_P(mesg))) {
- errat = make_backtrace();
- }
-
- if (!NIL_P(mesg)) {
- errinfo = mesg;
- }
trap_restore_mask();
if (trace_func && tag != TAG_FATAL) {
@@ -2724,14 +2720,14 @@ void
rb_raise(mesg)
VALUE mesg;
{
- rb_longjmp(TAG_RAISE, mesg, Qnil);
+ rb_longjmp(TAG_RAISE, mesg);
}
void
rb_fatal(mesg)
VALUE mesg;
{
- rb_longjmp(TAG_FATAL, mesg, Qnil);
+ rb_longjmp(TAG_FATAL, mesg);
}
void
@@ -2755,8 +2751,8 @@ f_raise(argc, argv)
case 1:
mesg = arg1;
break;
- case 2:
case 3:
+ case 2:
etype = arg1;
mesg = arg2;
break;
@@ -2769,11 +2765,15 @@ f_raise(argc, argv)
else if (TYPE(mesg) == T_STRING) {
mesg = exc_new3(eRuntimeError, mesg);
}
+ if (!obj_is_kind_of(mesg, eException)) {
+ TypeError("casting non-exception");
+ }
+ set_backtrace(mesg, arg3);
}
PUSH_FRAME(); /* fake frame */
*the_frame = *_frame.prev->prev;
- rb_longjmp(TAG_RAISE, mesg, arg3);
+ rb_longjmp(TAG_RAISE, mesg);
POP_FRAME();
}
@@ -3037,7 +3037,7 @@ handle_rescue(self, node)
TMP_PROTECT;
if (!node->nd_args) {
- return obj_is_kind_of(errinfo, eDefaultRescue);
+ return obj_is_kind_of(errinfo, eStandardError);
}
PUSH_ITER(ITER_NOT);
@@ -3060,13 +3060,14 @@ rb_rescue(b_proc, data1, r_proc, data2)
{
int state;
volatile VALUE result;
+ volatile VALUE e_info = errinfo;
PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
retry_entry:
result = (*b_proc)(data1);
}
- else if (state == TAG_RAISE && obj_is_kind_of(errinfo, eDefaultRescue)) {
+ else if (state == TAG_RAISE && obj_is_kind_of(errinfo, eStandardError)) {
if (r_proc) {
PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
@@ -3083,7 +3084,7 @@ rb_rescue(b_proc, data1, r_proc, data2)
state = 0;
}
if (state == 0) {
- errat = Qnil;
+ errinfo = e_info;
}
}
POP_TAG();
@@ -3826,9 +3827,11 @@ eval(self, src, scope, file, line)
sourcefile = filesave;
sourceline = linesave;
if (state) {
- VALUE err;
-
if (state == TAG_RAISE) {
+ VALUE err;
+ VALUE errat;
+
+ errat = get_backtrace(errinfo);
if (strcmp(file, "(eval)") == 0) {
if (sourceline > 1) {
err = RARRAY(errat)->ptr[0];
@@ -3841,7 +3844,7 @@ eval(self, src, scope, file, line)
errat = Qnil;
rb_raise(exc_new3(CLASS_OF(errinfo), err));
}
- rb_raise(Qnil);
+ rb_raise(errinfo);
}
JUMP_TAG(state);
}
@@ -4062,6 +4065,7 @@ f_load(obj, fname)
file = find_file(RSTRING(fname)->ptr);
if (!file) LoadError("No such file to load -- %s", RSTRING(fname)->ptr);
+ PUSH_VARS();
PUSH_TAG(PROT_NONE);
PUSH_CLASS();
the_class = cObject;
@@ -4097,6 +4101,7 @@ f_load(obj, fname)
POP_SCOPE();
POP_CLASS();
POP_TAG();
+ POP_VARS();
if (nerrs > 0) {
rb_raise(errinfo);
}
@@ -4472,7 +4477,24 @@ obj_extend(argc, argv, obj)
VALUE f_trace_var();
VALUE f_untrace_var();
-extern void rb_str_setter();
+static void
+errinfo_setter(val, id, var)
+ VALUE val;
+ ID id;
+ VALUE *var;
+{
+ if (!obj_is_kind_of(val, eException)) {
+ TypeError("assigning non-exception to $!");
+ }
+ *var = val;
+}
+
+static VALUE
+errat_getter(id)
+ ID id;
+{
+ return get_backtrace(errinfo);
+}
static void
errat_setter(val, id, var)
@@ -4480,7 +4502,10 @@ errat_setter(val, id, var)
ID id;
VALUE *var;
{
- *var = check_errat(val);
+ if (NIL_P(errinfo)) {
+ ArgError("$! not set");
+ }
+ set_backtrace(errinfo, val);
}
VALUE f_global_variables();
@@ -4589,8 +4614,8 @@ Init_eval()
rb_global_variable((VALUE*)&eval_tree);
rb_global_variable((VALUE*)&the_dyna_vars);
- rb_define_hooked_variable("$@", &errat, 0, errat_setter);
- rb_define_variable("$!", &errinfo);
+ rb_define_virtual_variable("$@", errat_getter, errat_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);
@@ -5253,7 +5278,7 @@ struct thread {
char *file;
int line;
- VALUE errat, errinfo;
+ VALUE errinfo;
VALUE last_status;
VALUE last_line;
VALUE last_match;
@@ -5315,7 +5340,6 @@ thread_mark(th)
gc_mark(th->scope);
gc_mark(th->dyna_vars);
- gc_mark(th->errat);
gc_mark(th->errinfo);
gc_mark(th->last_line);
gc_mark(th->last_match);
@@ -5398,7 +5422,6 @@ thread_save_context(th)
th->misc = scope_vmode | (trap_immediate<<8);
th->iter = the_iter;
th->tag = prot_tag;
- th->errat = errat;
th->errinfo = errinfo;
th->last_status = last_status;
th->last_line = lastline_get();
@@ -5459,7 +5482,6 @@ thread_restore_context(th, exit)
trap_immediate = th->misc>>8;
the_iter = th->iter;
prot_tag = th->tag;
- errat = th->errat;
errinfo = th->errinfo;
last_status = th->last_status;
safe_level = th->safe;
@@ -6051,7 +6073,6 @@ thread_alloc()
th->status = 0;
th->result = 0;
th->errinfo = Qnil;
- th->errat = Qnil;
th->stk_ptr = 0;
th->stk_len = 0;
@@ -6068,7 +6089,6 @@ thread_alloc()
th->block = 0;
th->iter = 0;
th->tag = 0;
- th->errat = 0;
th->errinfo = 0;
th->last_status = 0;
th->last_line = 0;
@@ -6157,7 +6177,6 @@ thread_create(fn, arg)
if (state == TAG_FATAL || obj_is_kind_of(errinfo, eSystemExit)) {
/* fatal error or global exit within this thread */
/* need to stop whole script */
- main_thread->errat = errat;
main_thread->errinfo = errinfo;
thread_cleanup();
}
@@ -6165,7 +6184,6 @@ thread_create(fn, arg)
f_abort();
}
else {
- curr_thread->errat = errat;
curr_thread->errinfo = errinfo;
}
}
@@ -6199,9 +6217,11 @@ thread_value(thread)
thread_join(0, thread);
if (!NIL_P(th->errinfo)) {
- errat = make_backtrace();
- ary_unshift(errat, ary_entry(th->errat, 0));
- sourcefile = 0; /* kludge to print errat */
+ VALUE oldbt = get_backtrace(th->errinfo);
+ VALUE errat = make_backtrace();
+
+ ary_unshift(errat, ary_entry(oldbt, 0));
+ set_backtrace(th->errinfo, errat);
rb_raise(th->errinfo);
}
diff --git a/intern.h b/intern.h
index af309fb3bc..ac02c72072 100644
--- a/intern.h
+++ b/intern.h
@@ -246,6 +246,7 @@ VALUE str_new2 _((UCHAR *));
VALUE str_new3 _((VALUE));
VALUE str_new4 _((VALUE));
VALUE obj_as_string _((VALUE));
+VALUE str_to_str _((VALUE));
VALUE str_dup _((VALUE));
VALUE str_plus _((VALUE, VALUE));
VALUE str_times _((VALUE, VALUE));
diff --git a/lib/pstore.rb b/lib/pstore.rb
index b93420d649..3f95e8c059 100644
--- a/lib/pstore.rb
+++ b/lib/pstore.rb
@@ -15,7 +15,8 @@
require "marshal"
class PStore
- Exception(:Error)
+ class Error < StandardError
+ end
def initialize(file)
dir = File::dirname(file)
@@ -90,13 +91,17 @@ class PStore
end
ensure
unless @abort
- File::rename @filename, @filename+"~"
+ begin
+ File::rename @filename, @filename+"~"
+ rescue Errno::ENOENT
+ no_orig = true
+ end
begin
File::open(@filename, "w") do |file|
Marshal::dump(@table, file)
end
rescue
- File::rename @filename+"~", @filename
+ File::rename @filename+"~", @filename unless no_orig
end
end
@abort = false
diff --git a/lib/weakref.rb b/lib/weakref.rb
index 6a6dcec5a1..6ef4b422c8 100644
--- a/lib/weakref.rb
+++ b/lib/weakref.rb
@@ -12,7 +12,8 @@ require "delegate"
class WeakRef<Delegator
- Exception :RefError
+ class RefError<StandardError
+ end
ID_MAP = {}
ID_REV_MAP = {}
diff --git a/object.c b/object.c
index f57a3cebda..65f5fe920b 100644
--- a/object.c
+++ b/object.c
@@ -831,7 +831,7 @@ str2cstr(str, len)
{
if (NIL_P(str)) return NULL;
if (TYPE(str) != T_STRING) {
- str = rb_convert_type(str, T_STRING, "String", "to_str");
+ str = str_to_str(str);
}
if (len) *len = RSTRING(str)->len;
return RSTRING(str)->ptr;
diff --git a/re.c b/re.c
index daf285708c..d4455c349b 100644
--- a/re.c
+++ b/re.c
@@ -411,37 +411,38 @@ reg_prepare_re(reg)
}
int
-reg_search(reg, str, start, regs)
+reg_search(reg, str, start, reverse)
VALUE reg, str;
- int start;
- struct re_registers *regs;
+ int start, reverse;
{
int result;
int casefold = RTEST(ignorecase);
VALUE match = 0;
- struct re_registers *regs0 = 0;
+ struct re_registers *regs = 0;
+ int range;
int need_recompile = 0;
if (start > RSTRING(str)->len) return -1;
reg_prepare_re(reg);
- if (regs == (struct re_registers*)-1) {
- regs = 0;
+ if (matchcache) {
+ match = matchcache;
+ matchcache = 0;
}
else {
- if (matchcache) {
- match = matchcache;
- matchcache = 0;
- }
- else {
- match = match_alloc();
- }
- regs0 = RMATCH(match)->regs;
+ match = match_alloc();
}
+ regs = RMATCH(match)->regs;
+ if (reverse) {
+ range = -start;
+ }
+ else {
+ range = RSTRING(str)->len-start;
+ }
result = re_search(RREGEXP(reg)->ptr,RSTRING(str)->ptr,RSTRING(str)->len,
- start,RSTRING(str)->len-start,regs0);
+ start, range, regs);
kcode_reset_option();
if (start == -2) {
@@ -456,7 +457,6 @@ reg_search(reg, str, start, regs)
RMATCH(match)->str = str_new4(str);
backref_set(match);
}
- if (regs && regs0) re_copy_registers(regs, regs0);
return result;
}
@@ -725,7 +725,7 @@ reg_match(re, str)
{
int start;
- if (TYPE(str) != T_STRING) return FALSE;
+ str = str_to_str(str);
start = reg_search(re, str, 0, 0);
if (start < 0) {
return FALSE;
diff --git a/re.h b/re.h
index dd93168ab1..bfc60d9fa5 100644
--- a/re.h
+++ b/re.h
@@ -31,7 +31,7 @@ struct RMatch {
int str_cicmp _((VALUE, VALUE));
VALUE reg_regcomp _((VALUE));
-int reg_search _((VALUE, VALUE, int, struct re_registers *));
+int reg_search _((VALUE, VALUE, int, int));
VALUE reg_regsub _((VALUE, VALUE, struct re_registers *));
void reg_free _((Regexp *));
#endif
diff --git a/ruby.c b/ruby.c
index 0a947472d9..9e8dedd15c 100644
--- a/ruby.c
+++ b/ruby.c
@@ -14,7 +14,6 @@
#include <windows.h>
#endif
#include "ruby.h"
-#include "re.h"
#include "dln.h"
#include <stdio.h>
#include <ctype.h>
@@ -191,6 +190,7 @@ proc_options(argcp, argvp)
case 'd':
debug = TRUE;
+ verbose |= 1;
s++;
goto reswitch;
@@ -781,9 +781,6 @@ ruby_process_options(argc, argv)
int argc;
char **argv;
{
- extern VALUE errat;
- int i;
-
origargc = argc; origargv = argv;
ruby_script(argv[0]); /* for the time being */
rb_argv0 = str_taint(str_new2(argv[0]));
diff --git a/sample/test.rb b/sample/test.rb
index f09619b827..912f84e2d4 100644
--- a/sample/test.rb
+++ b/sample/test.rb
@@ -674,7 +674,7 @@ if defined? Process.kill
rescue
x = $!
end
- ok(x && x =~ /Interrupt/)
+ ok(x && /Interrupt/ =~ x)
end
check "eval"
diff --git a/string.c b/string.c
index f94e457cef..f355f8e597 100644
--- a/string.c
+++ b/string.c
@@ -106,8 +106,8 @@ str_new4(orig)
}
}
-static VALUE
-to_str(str)
+VALUE
+str_to_str(str)
VALUE str;
{
return rb_convert_type(str, T_STRING, "String", "to_str");
@@ -173,7 +173,7 @@ str_dup(str)
{
VALUE s;
- str = to_str(str);
+ str = 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))
@@ -228,7 +228,7 @@ str_plus(str1, str2)
{
VALUE str3;
- str2 = to_str(str2);
+ str2 = str_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);
@@ -449,7 +449,7 @@ VALUE
str_concat(str1, str2)
VALUE str1, str2;
{
- str2 = to_str(str2);
+ str2 = str_to_str(str2);
str_cat(str1, RSTRING(str2)->ptr, RSTRING(str2)->len);
return str1;
}
@@ -530,7 +530,7 @@ str_cmp_method(str1, str2)
{
int result;
- str2 = to_str(str2);
+ str2 = str_to_str(str2);
result = str_cmp(str1, str2);
return INT2FIX(result);
}
@@ -607,7 +607,7 @@ str_index_method(argc, argv, str)
switch (TYPE(sub)) {
case T_REGEXP:
- pos = reg_search(sub, str, pos, (struct re_registers *)-1);
+ pos = reg_search(sub, str, pos, 0);
break;
case T_STRING:
@@ -655,11 +655,7 @@ str_rindex(argc, argv, str)
switch (TYPE(sub)) {
case T_REGEXP:
- reg_prepare_re(sub);
- pos = re_search(RREGEXP(sub)->ptr,
- RSTRING(str)->ptr, RSTRING(str)->len,
- pos, -pos, 0);
- kcode_reset_option();
+ pos = reg_search(sub, str, pos, 1);
if (pos >= 0) return INT2FIX(pos);
break;
@@ -770,7 +766,7 @@ str_upto(beg, end)
{
VALUE current;
- end = to_str(end);
+ end = str_to_str(end);
if (RTEST(rb_funcall(beg, '>', 1, end)))
return Qnil;
@@ -1120,7 +1116,7 @@ str_aset_method(argc, argv, str)
if (rb_scan_args(argc, argv, "21", &arg1, &arg2, &arg3) == 3) {
int beg, len;
- arg3 = to_str(arg3);
+ arg3 = str_to_str(arg3);
beg = NUM2INT(arg1);
if (beg < 0) {
beg = RSTRING(str)->len + beg;
@@ -1205,7 +1201,7 @@ static VALUE
str_replace_method(str, str2)
VALUE str, str2;
{
- str2 = to_str(str2);
+ str2 = str_to_str(str2);
str_modify(str);
str_resize(str, RSTRING(str2)->len);
memcpy(RSTRING(str)->ptr, RSTRING(str2)->ptr, RSTRING(str2)->len);
@@ -1353,7 +1349,7 @@ str_include(str, arg)
return FALSE;
}
- i = str_index(str, to_str(arg), 0);
+ i = str_index(str, str_to_str(arg), 0);
if (i == -1) return FALSE;
return INT2FIX(i);
@@ -1755,13 +1751,13 @@ tr_trans(str, src, repl, sflag)
UCHAR *s, *send;
str_modify(str);
- src = to_str(src);
+ src = str_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++;
}
- repl = to_str(repl);
+ repl = str_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;
@@ -1890,7 +1886,7 @@ str_delete_bang(str1, str2)
UCHAR squeez[256];
int modify = 0;
- str2 = to_str(str2);
+ str2 = str_to_str(str2);
tr_setup_table(str2, squeez);
str_modify(str1);
@@ -1968,7 +1964,7 @@ str_squeeze_bang(argc, argv, str1)
VALUE str2;
if (rb_scan_args(argc, argv, "01", &str2) == 1) {
- str2 = to_str(str2);
+ str2 = str_to_str(str2);
}
return tr_squeeze(str1, str2);
}
@@ -2145,7 +2141,7 @@ str_split(str, sep0)
{
VALUE sep;
- str = to_str(str);
+ str = str_to_str(str);
sep = str_new2(sep0);
return str_split_method(1, &sep, str);
}
@@ -2180,7 +2176,7 @@ str_each_line(argc, argv, str)
rb_yield(str);
return Qnil;
}
- rs = to_str(rs);
+ rs = str_to_str(rs);
rslen = RSTRING(rs)->len;
if (rslen == 0) {
@@ -2293,7 +2289,7 @@ str_chomp_bang(argc, argv, str)
}
if (NIL_P(rs)) return Qnil;
- rs = to_str(rs);
+ rs = str_to_str(rs);
rslen = RSTRING(rs)->len;
if (rslen == 0) {
while (len>0 && p[len-1] == '\n') {
@@ -2490,7 +2486,7 @@ str_crypt(str, salt)
{
extern char *crypt();
- salt = to_str(salt);
+ salt = str_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));