From 210367ec889f5910e270d6ea2c7ddb8a8d939e61 Mon Sep 17 00:00:00 2001 From: matz Date: Wed, 20 Jan 1999 04:59:39 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r372, which included commits to RCS files with non-trunk default branches. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@373 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- error.c | 656 +++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 461 insertions(+), 195 deletions(-) (limited to 'error.c') diff --git a/error.c b/error.c index 7163f62609..44ca067472 100644 --- a/error.c +++ b/error.c @@ -6,56 +6,46 @@ $Date$ created at: Mon Aug 9 16:11:34 JST 1993 - Copyright (C) 1993-1996 Yukihiro Matsumoto + Copyright (C) 1993-1998 Yukihiro Matsumoto ************************************************/ #include "ruby.h" #include "env.h" #include +#ifdef HAVE_STDARG_PROTOTYPES +#include +#define va_init_list(a,b) va_start(a,b) +#else #include +#define va_init_list(a,b) va_start(a) +#endif -extern char *sourcefile; -extern int sourceline; +#ifdef USE_CWGUSI +#include +int sys_nerr = 256; +#endif -int nerrs; +int ruby_nerrs; static void -err_sprintf(buf, fmt, args) +err_snprintf(buf, len, fmt, args) char *buf, *fmt; + int len; va_list args; { - if (!sourcefile) { - vsprintf(buf, fmt, args); + if (!ruby_sourcefile) { + vsnprintf(buf, len, fmt, args); } else { - sprintf(buf, "%s:%d: ", sourcefile, sourceline); - vsprintf((char*)buf+strlen(buf), fmt, args); - } -} - -static void -err_append(s) - char *s; -{ - extern VALUE errinfo; - - if (rb_in_eval) { - if (NIL_P(errinfo)) { - errinfo = str_new2(s); + int n = snprintf(buf, len, "%s:%d: ", ruby_sourcefile, ruby_sourceline); + if (len > n) { + vsnprintf((char*)buf+n, len-n, fmt, args); } - else { - str_cat(errinfo, "\n", 1); - str_cat(errinfo, s, strlen(s)); - } - } - else { - fputs(s, stderr); - fputs("\n", stderr); - fflush(stderr); } } +static void err_append _((char*)); static void err_print(fmt, args) char *fmt; @@ -63,66 +53,102 @@ err_print(fmt, args) { char buf[BUFSIZ]; - err_sprintf(buf, fmt, args); + err_snprintf(buf, BUFSIZ, fmt, args); err_append(buf); } void -Error(fmt, va_alist) +#ifdef HAVE_STDARG_PROTOTYPES +rb_compile_error(char *fmt, ...) +#else +rb_compile_error(fmt, va_alist) char *fmt; va_dcl +#endif { va_list args; - va_start(args); + va_init_list(args, fmt); err_print(fmt, args); va_end(args); - nerrs++; + ruby_nerrs++; } void -Error_Append(fmt, va_alist) +#ifdef HAVE_STDARG_PROTOTYPES +rb_compile_error_append(char *fmt, ...) +#else +rb_compile_error_append(fmt, va_alist) char *fmt; va_dcl +#endif { va_list args; char buf[BUFSIZ]; - va_start(args); - vsprintf(buf, fmt, args); + va_init_list(args, fmt); + vsnprintf(buf, BUFSIZ, fmt, args); va_end(args); err_append(buf); } void -Warning(fmt, va_alist) +#ifdef HAVE_STDARG_PROTOTYPES +rb_warn(char *fmt, ...) +#else +rb_warn(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + char buf[BUFSIZ]; + va_list args; + + snprintf(buf, BUFSIZ, "warning: %s", fmt); + + va_init_list(args, fmt); + err_print(buf, args); + va_end(args); +} + +/* rb_warning() reports only in verbose mode */ +void +#ifdef HAVE_STDARG_PROTOTYPES +rb_warning(char *fmt, ...) +#else +rb_warning(fmt, va_alist) char *fmt; va_dcl +#endif { char buf[BUFSIZ]; va_list args; - if (!RTEST(verbose)) return; + if (!RTEST(rb_verbose)) return; - sprintf(buf, "warning: %s", fmt); + snprintf(buf, BUFSIZ, "warning: %s", fmt); - va_start(args); + va_init_list(args, fmt); err_print(buf, args); va_end(args); } void -Bug(fmt, va_alist) +#ifdef HAVE_STDARG_PROTOTYPES +rb_bug(char *fmt, ...) +#else +rb_bug(fmt, va_alist) char *fmt; va_dcl +#endif { char buf[BUFSIZ]; va_list args; - sprintf(buf, "[BUG] %s", fmt); + snprintf(buf, BUFSIZ, "[BUG] %s", fmt); rb_in_eval = 0; - va_start(args); + va_init_list(args, fmt); err_print(buf, args); va_end(args); abort(); @@ -156,94 +182,133 @@ static struct types { -1, 0, }; -extern void TypeError(); - void rb_check_type(x, t) VALUE x; int t; { struct types *type = builtin_types; + int tt = TYPE(x); - if (TYPE(x)!=(t)) { + if (tt != t) { while (type->type >= 0) { if (type->type == t) { - TypeError("wrong argument type %s (expected %s)", - rb_class2name(CLASS_OF(x)), type->name); + char *etype; + + if (NIL_P(x)) { + etype = "nil"; + } + else if (FIXNUM_P(x)) { + etype = "Fixnum"; + } + else if (rb_special_const_p(x)) { + etype = RSTRING(rb_obj_as_string(x))->ptr; + } + else { + etype = rb_class2name(CLASS_OF(x)); + } + rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", + etype, type->name); } type++; } - Bug("unknown type 0x%x", t); + rb_bug("unknown type 0x%x", t); } } /* exception classes */ -#include "errno.h" - -extern VALUE cString; -VALUE eGlobalExit, eException; -VALUE eSystemExit, eInterrupt, eFatal; -VALUE eRuntimeError; -VALUE eSyntaxError; -VALUE eTypeError; -VALUE eArgError; -VALUE eNameError; -VALUE eIndexError; -VALUE eNotImpError; -VALUE eLoadError; -VALUE eSecurityError; - -VALUE eSystemCallError; -VALUE mErrno; +#include + +VALUE rb_eException; +VALUE rb_eSystemExit, rb_eInterrupt, rb_eFatal; +VALUE rb_eStandardError; +VALUE rb_eRuntimeError; +VALUE rb_eSyntaxError; +VALUE rb_eTypeError; +VALUE rb_eArgError; +VALUE rb_eNameError; +VALUE rb_eIndexError; +VALUE rb_eLoadError; +VALUE rb_eSecurityError; +VALUE rb_eNotImpError; + +VALUE rb_eSystemCallError; +VALUE rb_mErrno; VALUE -exc_new(etype, ptr, len) +rb_exc_new(etype, ptr, len) VALUE etype; char *ptr; - UINT len; + int len; { - NEWOBJ(exc, struct RString); - OBJSETUP(exc, etype, T_STRING); - - 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; + VALUE exc = rb_obj_alloc(etype); + + rb_iv_set(exc, "mesg", rb_str_new(ptr, len)); + return exc; } VALUE -exc_new2(etype, s) +rb_exc_new2(etype, s) VALUE etype; char *s; { - return exc_new(etype, s, strlen(s)); + return rb_exc_new(etype, s, strlen(s)); } VALUE -exc_new3(etype, str) +rb_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 rb_exc_new(etype, s, len); } static VALUE -exc_s_new(argc, argv, etype) +exc_initialize(argc, argv, exc) int argc; VALUE *argv; - VALUE etype; + VALUE exc; { - VALUE arg; + VALUE mesg; - if (rb_scan_args(argc, argv, "01", &arg) == 0) { - return exc_new(etype, 0, 0); + if (rb_scan_args(argc, argv, "01", &mesg) == 1) { + STR2CSTR(mesg); /* ensure mesg can be converted to String */ } - Check_Type(arg, T_STRING); - return exc_new3(etype, arg); + rb_iv_set(exc, "mesg", mesg); + + return exc; +} + +static VALUE +exc_new(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; +{ + VALUE etype, exc; + + if (argc == 1 && self == argv[0]) return self; + etype = CLASS_OF(self); + while (FL_TEST(etype, FL_SINGLETON)) { + etype = RCLASS(etype)->super; + } + exc = rb_obj_alloc(etype); + rb_obj_call_init(exc); + + return exc; +} + +static VALUE +exc_to_s(exc) + VALUE exc; +{ + VALUE mesg = rb_iv_get(exc, "mesg"); + + if (NIL_P(mesg)) return rb_class_path(CLASS_OF(exc)); + return mesg; } static VALUE @@ -253,185 +318,314 @@ exc_inspect(exc) VALUE str, klass; klass = CLASS_OF(exc); + exc = rb_obj_as_string(exc); if (RSTRING(exc)->len == 0) { - return rb_class_path(klass); + return rb_str_dup(rb_class_path(klass)); } - str = str_new2("#<"); + str = rb_str_new2("#<"); klass = rb_class_path(klass); - str_cat(str, RSTRING(klass)->ptr, RSTRING(klass)->len); - str_cat(str, ":", 1); - str_cat(str, RSTRING(exc)->ptr, RSTRING(exc)->len); - str_cat(str, ">", 1); + rb_str_concat(str, klass); + rb_str_cat(str, ":", 1); + rb_str_concat(str, exc); + rb_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 rb_ary_new3(1, bt); + if (t != T_ARRAY) { + rb_raise(rb_eTypeError, err); + } + for (i=0;ilen;i++) { + if (TYPE(RARRAY(bt)->ptr[i]) != T_STRING) { + rb_raise(rb_eTypeError, 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 v = Qnil; + VALUE etype = rb_eStandardError; int i; ID id; if (argc == 0) { - ArgError("wrong # of arguments"); + rb_raise(rb_eArgError, "wrong # of arguments"); + } + rb_warn("Exception() is now obsolete"); + if (TYPE(argv[argc-1]) == T_CLASS) { + etype = argv[argc-1]; + argc--; + if (!rb_funcall(etype, '<', 1, rb_eException)) { + rb_raise(rb_eTypeError, "exception should be subclass of Exception"); + } } for (i=0; i> 12) & 0xf; + offset = (i >> 8) & 0xf; + if (offset < syserr_index[ix].n) { + ix = syserr_index[ix].ix; + if ((i & 0xff) < syserr_list[ix + offset].n) { + list = syserr_list[ix + offset].list; + list[i & 0xff] = error; + rb_global_variable(&list[i & 0xff]); + } + } +#else if (i <= sys_nerr) { - syserr_list[i] = rb_define_class_under(mErrno, name, eSystemCallError); - rb_global_variable(&syserr_list[i]); + syserr_list[i] = error; } +#endif + return error; } -static void init_syserr(); +static VALUE +syserr_errno(self) + VALUE self; +{ + return rb_iv_get(self, "errno"); +} + +#ifdef __BEOS__ +static VALUE +get_syserr(int i) +{ + VALUE *list; + int ix, offset; + + i -= B_GENERAL_ERROR_BASE; + ix = (i >> 12) & 0xf; + offset = (i >> 8) & 0xf; + if (offset < syserr_index[ix].n) { + ix = syserr_index[ix].ix; + if ((i & 0xff) < syserr_list[ix + offset].n) { + list = syserr_list[ix + offset].list; + return list[i & 0xff]; + } + } + return 0; +} +#endif /* __BEOS__ */ + +static void init_syserr _((void)); void Init_Exception() { - eGlobalExit = rb_define_class("GlobalExit", cString); - rb_define_singleton_method(eGlobalExit, "new", exc_s_new, -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); - - eException = rb_define_class("Exception", eGlobalExit); - eSyntaxError = rb_define_class("SyntaxError", eException); - eTypeError = rb_define_class("TypeError", eException); - eArgError = rb_define_class("ArgumentError", eException); - eNameError = rb_define_class("NameError", eException); - eIndexError = rb_define_class("IndexError", eException); - eNotImpError = rb_define_class("NotImplementError", eException); - eLoadError = rb_define_class("LoadError", eException); - - eRuntimeError = rb_define_class("RuntimeError", eException); - eSecurityError = rb_define_class("SecurityError", eException); + rb_eException = rb_define_class("Exception", rb_cObject); + rb_define_method(rb_eException, "new", exc_new, -1); + rb_define_method(rb_eException, "initialize", exc_initialize, -1); + rb_define_method(rb_eException, "to_s", exc_to_s, 0); + rb_define_method(rb_eException, "to_str", exc_to_s, 0); + rb_define_method(rb_eException, "message", exc_to_s, 0); + rb_define_method(rb_eException, "inspect", exc_inspect, 0); + rb_define_method(rb_eException, "backtrace", exc_backtrace, 0); + rb_define_method(rb_eException, "set_backtrace", exc_set_backtrace, 1); + + rb_eSystemExit = rb_define_class("SystemExit", rb_eException); + rb_eFatal = rb_define_class("fatal", rb_eException); + rb_eInterrupt = rb_define_class("Interrupt", rb_eException); + + rb_eStandardError = rb_define_class("StandardError", rb_eException); + rb_eSyntaxError = rb_define_class("SyntaxError", rb_eStandardError); + rb_eTypeError = rb_define_class("TypeError", rb_eStandardError); + rb_eArgError = rb_define_class("ArgumentError", rb_eStandardError); + rb_eNameError = rb_define_class("NameError", rb_eStandardError); + rb_eIndexError = rb_define_class("IndexError", rb_eStandardError); + rb_eLoadError = rb_define_class("LoadError", rb_eStandardError); + + rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError); + rb_eSecurityError = rb_define_class("SecurityError", rb_eStandardError); + rb_eNotImpError = rb_define_class("NotImplementError", rb_eException); init_syserr(); rb_define_global_function("Exception", exception, -1); } -#define RAISE_ERROR(class) {\ - va_list args;\ - char buf[BUFSIZ];\ -\ - va_start(args);\ - vsprintf(buf, fmt, args);\ - va_end(args);\ -\ - rb_raise(exc_new2(class, buf));\ -} - void -Raise(exc, fmt, va_alist) +#ifdef HAVE_STDARG_PROTOTYPES +rb_raise(VALUE exc, char *fmt, ...) +#else +rb_raise(exc, fmt, va_alist) VALUE exc; char *fmt; va_dcl +#endif { - RAISE_ERROR(exc); -} - -void -TypeError(fmt, va_alist) - char *fmt; - va_dcl -{ - RAISE_ERROR(eTypeError); -} - -void -ArgError(fmt, va_alist) - char *fmt; - va_dcl -{ - RAISE_ERROR(eArgError); -} + va_list args; + char buf[BUFSIZ]; -void -NameError(fmt, va_alist) - char *fmt; - va_dcl -{ - RAISE_ERROR(eNameError); + va_init_list(args,fmt); + vsnprintf(buf, BUFSIZ, fmt, args); + va_end(args); + rb_exc_raise(rb_exc_new2(exc, buf)); } void -IndexError(fmt, va_alist) +#ifdef HAVE_STDARG_PROTOTYPES +rb_loaderror(char *fmt, ...) +#else +rb_loaderror(fmt, va_alist) char *fmt; va_dcl +#endif { - RAISE_ERROR(eIndexError); -} + va_list args; + char buf[BUFSIZ]; -void -Fail(fmt, va_alist) - char *fmt; - va_dcl -{ - RAISE_ERROR(eRuntimeError); + va_init_list(args, fmt); + vsnprintf(buf, BUFSIZ, fmt, args); + va_end(args); + rb_exc_raise(rb_exc_new2(rb_eLoadError, buf)); } void rb_notimplement() { - Raise(eNotImpError, - "The %s() function is unimplemented on this machine", - rb_id2name(the_frame->last_func)); + rb_raise(rb_eNotImpError, + "The %s() function is unimplemented on this machine", + rb_id2name(ruby_frame->last_func)); } void -LoadError(fmt, va_alist) - char *fmt; - va_dcl -{ - RAISE_ERROR(eLoadError); -} - -void -Fatal(fmt, va_alist) +#ifdef HAVE_STDARG_PROTOTYPES +rb_fatal(char *fmt, ...) +#else +rb_fatal(fmt, va_alist) char *fmt; va_dcl +#endif { va_list args; char buf[BUFSIZ]; - va_start(args); - vsprintf(buf, fmt, args); + va_init_list(args, fmt); + vsnprintf(buf, BUFSIZ, fmt, args); va_end(args); rb_in_eval = 0; - rb_fatal(exc_new2(eFatal, buf)); + rb_exc_fatal(rb_exc_new2(rb_eFatal, buf)); } void @@ -441,32 +635,79 @@ rb_sys_fail(mesg) #ifndef NT char *strerror(); #endif - char buf[BUFSIZ]; + char *err; + char *buf; extern int errno; int n = errno; + VALUE ee; - if (RTEST(mesg)) - sprintf(buf, "%s - %s", strerror(errno), mesg); - else - sprintf(buf, "%s", strerror(errno)); + err = strerror(errno); + if (mesg) { + buf = ALLOCA_N(char, strlen(err)+strlen(mesg)+4); + sprintf(buf, "%s - %s", err, mesg); + } + else { + buf = ALLOCA_N(char, strlen(err)+1); + strcpy(buf, err); + } errno = 0; +#ifdef __BEOS__ + ee = get_syserr(n); + if (!ee) { + char name[6]; + + sprintf(name, "E%03d", n); + ee = set_syserr(n, name); + } +#else +# ifdef USE_CWGUSI + if (n < 0) { + int macoserr_index = sys_nerr - 1; + if (!syserr_list[macoserr_index]) { + char name[6]; + sprintf(name, "E%03d", macoserr_index); + ee = set_syserr(macoserr_index, name); + } + } + else +#endif /* USE_CWGUSI */ if (n > sys_nerr || !syserr_list[n]) { char name[6]; sprintf(name, "E%03d", n); - set_syserr(n, name); + ee = set_syserr(n, name); + } + else { + ee = syserr_list[n]; } - rb_raise(exc_new2(syserr_list[n], buf)); + ee = rb_exc_new2(ee, buf); +#endif + rb_iv_set(ee, "errno", INT2FIX(n)); + rb_exc_raise(ee); } static void init_syserr() { - eSystemCallError = rb_define_class("SystemCallError", eException); - mErrno = rb_define_module("Errno"); +#ifdef __BEOS__ + int i, ix, offset; +#endif + rb_eSystemCallError = rb_define_class("SystemCallError", rb_eStandardError); + rb_define_method(rb_eSystemCallError, "errno", syserr_errno, 0); + + rb_mErrno = rb_define_module("Errno"); +#ifdef __BEOS__ + for (i = 0; syserr_index[i].n != 0; i++) { + ix = syserr_index[i].ix; + for (offset = 0; offset < syserr_index[i].n; offset++) { + MEMZERO(syserr_list[ix + offset].list, VALUE, syserr_list[ix + offset].n); + } + } +#else syserr_list = ALLOC_N(VALUE, sys_nerr+1); MEMZERO(syserr_list, VALUE, sys_nerr+1); +#endif #ifdef EPERM set_syserr(EPERM, "EPERM"); @@ -835,3 +1076,28 @@ init_syserr() set_syserr(EDQUOT, "EDQUOT"); #endif } + +static void +err_append(s) + char *s; +{ + extern VALUE rb_errinfo; + + if (rb_in_eval) { + if (NIL_P(rb_errinfo)) { + rb_errinfo = rb_exc_new2(rb_eSyntaxError, s); + } + else { + VALUE str = rb_str_to_str(rb_errinfo); + + rb_str_cat(str, "\n", 1); + rb_str_cat(str, s, strlen(s)); + rb_errinfo = rb_exc_new3(rb_eSyntaxError, str); + } + } + else { + fputs(s, stderr); + fputs("\n", stderr); + fflush(stderr); + } +} -- cgit v1.2.3