1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/error.c

1239 lines
25 KiB
C
Raw Normal View History

/**********************************************************************
error.c -
$Author$
$Date$
created at: Mon Aug 9 16:11:34 JST 1993
Copyright (C) 1993-2002 Yukihiro Matsumoto
**********************************************************************/
#include "ruby.h"
#include "env.h"
#include "version.h"
#include <stdio.h>
#ifdef HAVE_STDARG_PROTOTYPES
#include <stdarg.h>
#define va_init_list(a,b) va_start(a,b)
#else
#include <varargs.h>
#define va_init_list(a,b) va_start(a)
#endif
#if defined __CYGWIN__
# include <cygwin/version.h>
# if (CYGWIN_VERSION_API_MAJOR > 0) || (CYGWIN_VERSION_API_MINOR >= 8)
# define sys_nerr _sys_nerr
# endif
#endif
int ruby_nerrs;
static void
err_snprintf(buf, len, fmt, args)
char *buf, *fmt;
long len;
va_list args;
{
long n;
ruby_set_current_source();
if (!ruby_sourcefile) {
vsnprintf(buf, len, fmt, args);
return;
}
else if (ruby_sourceline == 0) {
n = snprintf(buf, len, "%s: ", ruby_sourcefile);
}
else {
n = snprintf(buf, len, "%s:%d: ", ruby_sourcefile, ruby_sourceline);
}
if (len > n) {
vsnprintf((char*)buf+n, len-n, fmt, args);
}
}
static void err_append _((const char*));
static void
err_print(fmt, args)
const char *fmt;
va_list args;
{
char buf[BUFSIZ];
err_snprintf(buf, BUFSIZ, fmt, args);
err_append(buf);
}
void
#ifdef HAVE_STDARG_PROTOTYPES
rb_compile_error(const char *fmt, ...)
#else
rb_compile_error(fmt, va_alist)
const char *fmt;
va_dcl
#endif
{
va_list args;
va_init_list(args, fmt);
err_print(fmt, args);
va_end(args);
ruby_nerrs++;
}
void
#ifdef HAVE_STDARG_PROTOTYPES
rb_compile_error_append(const char *fmt, ...)
#else
rb_compile_error_append(fmt, va_alist)
const char *fmt;
va_dcl
#endif
{
va_list args;
char buf[BUFSIZ];
va_init_list(args, fmt);
vsnprintf(buf, BUFSIZ, fmt, args);
va_end(args);
err_append(buf);
}
static void
warn_print(fmt, args)
const char *fmt;
va_list args;
{
char buf[BUFSIZ];
err_snprintf(buf, BUFSIZ, fmt, args);
fputs(buf, stderr);
fputs("\n", stderr);
fflush(stderr);
}
void
#ifdef HAVE_STDARG_PROTOTYPES
rb_warn(const char *fmt, ...)
#else
rb_warn(fmt, va_alist)
const char *fmt;
va_dcl
#endif
{
char buf[BUFSIZ];
va_list args;
snprintf(buf, BUFSIZ, "warning: %s", fmt);
va_init_list(args, fmt);
warn_print(buf, args);
va_end(args);
}
/* rb_warning() reports only in verbose mode */
void
#ifdef HAVE_STDARG_PROTOTYPES
rb_warning(const char *fmt, ...)
#else
rb_warning(fmt, va_alist)
const char *fmt;
va_dcl
#endif
{
char buf[BUFSIZ];
va_list args;
if (!RTEST(ruby_verbose)) return;
snprintf(buf, BUFSIZ, "warning: %s", fmt);
va_init_list(args, fmt);
warn_print(buf, args);
va_end(args);
}
void
#ifdef HAVE_STDARG_PROTOTYPES
rb_bug(const char *fmt, ...)
#else
rb_bug(fmt, va_alist)
const char *fmt;
va_dcl
#endif
{
char buf[BUFSIZ];
va_list args;
snprintf(buf, BUFSIZ, "[BUG] %s", fmt);
ruby_in_eval = 0;
va_init_list(args, fmt);
warn_print(buf, args);
va_end(args);
fprintf(stderr, "ruby %s (%s) [%s]\n", RUBY_VERSION, RUBY_RELEASE_DATE, RUBY_PLATFORM);
abort();
}
static struct types {
int type;
const char *name;
} builtin_types[] = {
{T_NIL, "nil"},
{T_OBJECT, "Object"},
{T_CLASS, "Class"},
{T_ICLASS, "iClass"}, /* internal use: mixed-in module holder */
{T_MODULE, "Module"},
{T_FLOAT, "Float"},
{T_STRING, "String"},
{T_REGEXP, "Regexp"},
{T_ARRAY, "Array"},
{T_FIXNUM, "Fixnum"},
{T_HASH, "Hash"},
{T_STRUCT, "Struct"},
{T_BIGNUM, "Bignum"},
{T_FILE, "File"},
{T_TRUE, "true"},
{T_FALSE, "false"},
{T_SYMBOL, "Symbol"}, /* :symbol */
{T_DATA, "Data"}, /* internal use: wrapped C pointers */
{T_MATCH, "MatchData"}, /* data of $~ */
{T_VARMAP, "Varmap"}, /* internal use: dynamic variables */
{T_SCOPE, "Scope"}, /* internal use: variable scope */
{T_NODE, "Node"}, /* internal use: syntax tree node */
{T_UNDEF, "undef"}, /* internal use: #undef; should not happen */
{-1, 0}
};
void
rb_check_type(x, t)
VALUE x;
int t;
{
struct types *type = builtin_types;
if (x == Qundef) {
rb_bug("undef leaked to the Ruby space");
}
if (TYPE(x) != t) {
while (type->type >= 0) {
if (type->type == t) {
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++;
}
rb_bug("unknown type 0x%x", t);
}
}
/* exception classes */
#include <errno.h>
VALUE rb_eException;
VALUE rb_eSystemExit;
VALUE rb_eInterrupt;
VALUE rb_eSignal;
VALUE rb_eFatal;
VALUE rb_eStandardError;
VALUE rb_eRuntimeError;
VALUE rb_eTypeError;
VALUE rb_eArgError;
VALUE rb_eIndexError;
VALUE rb_eRangeError;
VALUE rb_eNameError;
VALUE rb_eNoMethodError;
VALUE rb_eSecurityError;
VALUE rb_eNotImpError;
VALUE rb_eNoMemError;
VALUE rb_eScriptError;
VALUE rb_eSyntaxError;
VALUE rb_eLoadError;
VALUE rb_eSystemCallError;
VALUE rb_mErrno;
VALUE
rb_exc_new(etype, ptr, len)
VALUE etype;
const char *ptr;
long len;
{
return rb_funcall(etype, rb_intern("new"), 1, rb_str_new(ptr, len));
}
VALUE
rb_exc_new2(etype, s)
VALUE etype;
const char *s;
{
return rb_exc_new(etype, s, strlen(s));
}
VALUE
rb_exc_new3(etype, str)
VALUE etype, str;
{
* eval.c (block_pass): should not downgrade safe level. * ext/dbm/extconf.rb: allow specifying dbm-type explicitly. * ext/dbm/extconf.rb: avoid gdbm if possible, because it leaks memory, whereas gdbm.so doesn't. potential incompatibility. * string.c (rb_str_insert): new method. * parse.y (yylex): lex_state after RESCUE_MOD should be EXPR_BEG. * array.c (rb_ary_insert): new method. * array.c (rb_ary_update): new utility function. * io.c (set_outfile): should check if closed before assignment. * eval.c (rb_eval): should preserve value of ruby_errinfo. * eval.c (rb_thread_schedule): infinite sleep should not cause dead lock. * array.c (rb_ary_flatten_bang): proper recursive detection. * eval.c (yield_under): need not to prohibit at safe level 4. * pack.c (pack_pack): p/P packs nil into NULL. * pack.c (pack_unpack): p/P unpacks NULL into nil. * pack.c (pack_pack): size check for P template. * ruby.c (set_arg0): wrong predicate when new $0 value is bigger than original space. * gc.c (id2ref): should use NUM2ULONG() * object.c (rb_mod_const_get): check whether name is a class variable name. * object.c (rb_mod_const_set): ditto. * object.c (rb_mod_const_defined): ditto. * marshal.c (w_float): precision changed to "%.16g" * eval.c (rb_call0): wrong retry behavior. * numeric.c (fix_aref): a bug on long>int architecture. * eval.c (rb_eval_string_wrap): should restore ruby_wrapper. * regex.c (re_compile_pattern): char class at either edge of range should be invalid. * eval.c (handle_rescue): use === to compare exception match. * error.c (syserr_eqq): comparison between SytemCallErrors should based on their error numbers. * eval.c (safe_getter): should use INT2NUM(). * bignum.c (rb_big2long): 2**31 cannot fit in 31 bit long. * regex.c (calculate_must_string): wrong length calculation. * eval.c (rb_thread_start_0): fixed memory leak. * parse.y (none): should clear cmdarg_stack too. * io.c (rb_fopen): use setvbuf() to avoid recursive malloc() on some platforms. * file.c (rb_stat_dev): device functions should honor stat field types (except long long such as dev_t). * eval.c (rb_mod_nesting): should not push nil for nesting array. * eval.c (rb_mod_s_constants): should not search array by rb_mod_const_at() for nil (happens for singleton class). * class.c (rb_singleton_class_attached): should modify iv_tbl by itself, no longer use rb_iv_set() to avoid freeze check error. * variable.c (rb_const_get): error message "uninitialized constant Foo at Bar::Baz" instead of "uninitialized constantBar::Baz::Foo". * eval.c (rb_mod_included): new hook called from rb_mod_include(). * io.c (opt_i_set): should strdup() inplace_edit string. * eval.c (exec_under): need to push cref too. * eval.c (rb_f_missing): raise NameError for "undefined local variable or method". * error.c (Init_Exception): new exception NoMethodError. NameError moved under ScriptError again. * eval.c (rb_f_missing): use NoMethodError instead of NameError. * file.c (Init_File): should redifine "new" class method. * eval.c (PUSH_CREF): sharing cref node was problematic. maintain runtime cref list instead. * eval.c (rb_eval): copy defn node before registering. * eval.c (rb_load): clear ruby_cref before loading. * variable.c (rb_const_get): no recursion to show full class path for modules. * eval.c (rb_set_safe_level): should set safe level in curr_thread as well. * eval.c (safe_setter): ditto. * object.c (rb_obj_is_instance_of): nil belongs to false, not true. * time.c (make_time_t): proper (I hope) daylight saving time handling for both US and Europe. I HATE DST! * eval.c (rb_thread_wait_for): non blocked signal interrupt should stop the interval. * eval.c (proc_eq): class check aded. * eval.c (proc_eq): typo fixed ("return" was ommitted). * error.c (Init_Exception): move NameError under StandardError. * class.c (rb_mod_clone): should copy method bodies too. * bignum.c (bigdivrem): should trim trailing zero bdigits of remainder, even if dd == 0. * file.c (check3rdbyte): safe string check moved here. * time.c (make_time_t): remove HAVE_TM_ZONE code since it sometimes reports wrong time. * time.c (make_time_t): remove unnecessary range check for platforms where negative time_t is available. * process.c (proc_waitall): should push Process::Status instead of Finuxm status. * process.c (waitall_each): should add all entries in pid_tbl. these changes are inspired by Koji Arai. Thanks. * process.c (proc_wait): should not iterate if pid_tbl is 0. * process.c (proc_waitall): ditto. * numeric.c (flodivmod): a bug in no fmod case. * process.c (pst_wifsignaled): should apply WIFSIGNALED for status (int), not st (VALUE). * io.c (Init_IO): value of $/ and $\ are no longer restricted to strings. type checks are done on demand. * class.c (rb_include_module): module inclusion should be check taints. * ruby.h (STR2CSTR): replace to StringType() and StringTypePtr(). * ruby.h (rb_str2cstr): ditto. * eval.c (rb_load): should not copy topleve local variables. It cause variable/method ambiguity. Thanks to L. Peter Deutsch. * class.c (rb_include_module): freeze check at first. * eval.c (rb_attr): sprintf() and rb_intern() moved into conditional body. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1356 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2001-05-02 00:22:21 -04:00
StringValue(str);
return rb_exc_new(etype, RSTRING(str)->ptr, RSTRING(str)->len);
}
static VALUE
exc_initialize(argc, argv, exc)
int argc;
VALUE *argv;
VALUE exc;
{
VALUE mesg;
if (rb_scan_args(argc, argv, "01", &mesg) == 1) {
* eval.c (block_pass): should not downgrade safe level. * ext/dbm/extconf.rb: allow specifying dbm-type explicitly. * ext/dbm/extconf.rb: avoid gdbm if possible, because it leaks memory, whereas gdbm.so doesn't. potential incompatibility. * string.c (rb_str_insert): new method. * parse.y (yylex): lex_state after RESCUE_MOD should be EXPR_BEG. * array.c (rb_ary_insert): new method. * array.c (rb_ary_update): new utility function. * io.c (set_outfile): should check if closed before assignment. * eval.c (rb_eval): should preserve value of ruby_errinfo. * eval.c (rb_thread_schedule): infinite sleep should not cause dead lock. * array.c (rb_ary_flatten_bang): proper recursive detection. * eval.c (yield_under): need not to prohibit at safe level 4. * pack.c (pack_pack): p/P packs nil into NULL. * pack.c (pack_unpack): p/P unpacks NULL into nil. * pack.c (pack_pack): size check for P template. * ruby.c (set_arg0): wrong predicate when new $0 value is bigger than original space. * gc.c (id2ref): should use NUM2ULONG() * object.c (rb_mod_const_get): check whether name is a class variable name. * object.c (rb_mod_const_set): ditto. * object.c (rb_mod_const_defined): ditto. * marshal.c (w_float): precision changed to "%.16g" * eval.c (rb_call0): wrong retry behavior. * numeric.c (fix_aref): a bug on long>int architecture. * eval.c (rb_eval_string_wrap): should restore ruby_wrapper. * regex.c (re_compile_pattern): char class at either edge of range should be invalid. * eval.c (handle_rescue): use === to compare exception match. * error.c (syserr_eqq): comparison between SytemCallErrors should based on their error numbers. * eval.c (safe_getter): should use INT2NUM(). * bignum.c (rb_big2long): 2**31 cannot fit in 31 bit long. * regex.c (calculate_must_string): wrong length calculation. * eval.c (rb_thread_start_0): fixed memory leak. * parse.y (none): should clear cmdarg_stack too. * io.c (rb_fopen): use setvbuf() to avoid recursive malloc() on some platforms. * file.c (rb_stat_dev): device functions should honor stat field types (except long long such as dev_t). * eval.c (rb_mod_nesting): should not push nil for nesting array. * eval.c (rb_mod_s_constants): should not search array by rb_mod_const_at() for nil (happens for singleton class). * class.c (rb_singleton_class_attached): should modify iv_tbl by itself, no longer use rb_iv_set() to avoid freeze check error. * variable.c (rb_const_get): error message "uninitialized constant Foo at Bar::Baz" instead of "uninitialized constantBar::Baz::Foo". * eval.c (rb_mod_included): new hook called from rb_mod_include(). * io.c (opt_i_set): should strdup() inplace_edit string. * eval.c (exec_under): need to push cref too. * eval.c (rb_f_missing): raise NameError for "undefined local variable or method". * error.c (Init_Exception): new exception NoMethodError. NameError moved under ScriptError again. * eval.c (rb_f_missing): use NoMethodError instead of NameError. * file.c (Init_File): should redifine "new" class method. * eval.c (PUSH_CREF): sharing cref node was problematic. maintain runtime cref list instead. * eval.c (rb_eval): copy defn node before registering. * eval.c (rb_load): clear ruby_cref before loading. * variable.c (rb_const_get): no recursion to show full class path for modules. * eval.c (rb_set_safe_level): should set safe level in curr_thread as well. * eval.c (safe_setter): ditto. * object.c (rb_obj_is_instance_of): nil belongs to false, not true. * time.c (make_time_t): proper (I hope) daylight saving time handling for both US and Europe. I HATE DST! * eval.c (rb_thread_wait_for): non blocked signal interrupt should stop the interval. * eval.c (proc_eq): class check aded. * eval.c (proc_eq): typo fixed ("return" was ommitted). * error.c (Init_Exception): move NameError under StandardError. * class.c (rb_mod_clone): should copy method bodies too. * bignum.c (bigdivrem): should trim trailing zero bdigits of remainder, even if dd == 0. * file.c (check3rdbyte): safe string check moved here. * time.c (make_time_t): remove HAVE_TM_ZONE code since it sometimes reports wrong time. * time.c (make_time_t): remove unnecessary range check for platforms where negative time_t is available. * process.c (proc_waitall): should push Process::Status instead of Finuxm status. * process.c (waitall_each): should add all entries in pid_tbl. these changes are inspired by Koji Arai. Thanks. * process.c (proc_wait): should not iterate if pid_tbl is 0. * process.c (proc_waitall): ditto. * numeric.c (flodivmod): a bug in no fmod case. * process.c (pst_wifsignaled): should apply WIFSIGNALED for status (int), not st (VALUE). * io.c (Init_IO): value of $/ and $\ are no longer restricted to strings. type checks are done on demand. * class.c (rb_include_module): module inclusion should be check taints. * ruby.h (STR2CSTR): replace to StringType() and StringTypePtr(). * ruby.h (rb_str2cstr): ditto. * eval.c (rb_load): should not copy topleve local variables. It cause variable/method ambiguity. Thanks to L. Peter Deutsch. * class.c (rb_include_module): freeze check at first. * eval.c (rb_attr): sprintf() and rb_intern() moved into conditional body. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1356 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2001-05-02 00:22:21 -04:00
StringValue(mesg); /* ensure mesg can be converted to String */
}
rb_iv_set(exc, "mesg", mesg);
rb_iv_set(exc, "bt", Qnil);
return exc;
}
static VALUE
exc_exception(argc, argv, self)
int argc;
VALUE *argv;
VALUE self;
{
* error.c (exc_exception): clone the receiver exception instead of creating brand new exception object of the receiver. * eval.c (rb_eval_string_wrap): extend new ruby_top_self, not original self. * eval.c (rb_eval_cmd): respect ruby_wrapper if set. * eval.c (eval): do not update ruby_class unless scope is not provided. * eval.c (eval): preserve wrapper information. * eval.c (proc_invoke): ditto. * eval.c (block_pass): ditto. * parse.y (void_expr): too much warnings for void context (e.g. foo[1] that can be mere Proc call). * error.c (rb_name_error): new function to raise NameError with name attribute set. * eval.c (rb_f_missing): set name and args in the exception object. [new] * error.c (name_name): NameError#name - new method. * error.c (nometh_args): NoMethodError#args - new method. * lex.c (rb_reserved_word): lex_state after tRESCUE should be EXPR_MID. * gc.c (add_heap): allocation size of the heap unit is doubled for each allocation. * dir.c (isdelim): space, tab, and newline are no longer delimiters for glob patterns. * eval.c (svalue_to_avalue): new conversion scheme between single value and array values. * eval.c (avalue_to_svalue): ditto. * eval.c (rb_eval): REXPAND now uses avalue_to_svalue(), return and yield too. * eval.c (rb_yield_0): use avalue_to_svalue(). * eval.c (proc_invoke): Proc#call gives avaules, whereas Proc#yield gives mvalues. * eval.c (bmcall): convert given value (svalue) to avalue. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1555 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2001-07-02 04:46:28 -04:00
VALUE exc;
if (argc == 0) return self;
if (argc == 1 && self == argv[0]) return self;
* error.c (exc_exception): clone the receiver exception instead of creating brand new exception object of the receiver. * eval.c (rb_eval_string_wrap): extend new ruby_top_self, not original self. * eval.c (rb_eval_cmd): respect ruby_wrapper if set. * eval.c (eval): do not update ruby_class unless scope is not provided. * eval.c (eval): preserve wrapper information. * eval.c (proc_invoke): ditto. * eval.c (block_pass): ditto. * parse.y (void_expr): too much warnings for void context (e.g. foo[1] that can be mere Proc call). * error.c (rb_name_error): new function to raise NameError with name attribute set. * eval.c (rb_f_missing): set name and args in the exception object. [new] * error.c (name_name): NameError#name - new method. * error.c (nometh_args): NoMethodError#args - new method. * lex.c (rb_reserved_word): lex_state after tRESCUE should be EXPR_MID. * gc.c (add_heap): allocation size of the heap unit is doubled for each allocation. * dir.c (isdelim): space, tab, and newline are no longer delimiters for glob patterns. * eval.c (svalue_to_avalue): new conversion scheme between single value and array values. * eval.c (avalue_to_svalue): ditto. * eval.c (rb_eval): REXPAND now uses avalue_to_svalue(), return and yield too. * eval.c (rb_yield_0): use avalue_to_svalue(). * eval.c (proc_invoke): Proc#call gives avaules, whereas Proc#yield gives mvalues. * eval.c (bmcall): convert given value (svalue) to avalue. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1555 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2001-07-02 04:46:28 -04:00
exc = rb_obj_clone(self);
exc_initialize(argc, argv, 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));
if (OBJ_TAINTED(exc)) OBJ_TAINT(mesg);
return mesg;
}
static VALUE
exc_inspect(exc)
VALUE exc;
{
VALUE str, klass;
klass = CLASS_OF(exc);
exc = rb_obj_as_string(exc);
if (RSTRING(exc)->len == 0) {
return rb_str_dup(rb_class_path(klass));
}
str = rb_str_buf_new2("#<");
klass = rb_class_path(klass);
rb_str_buf_append(str, klass);
rb_str_buf_cat(str, ": ", 2);
rb_str_buf_append(str, exc);
rb_str_buf_cat(str, ">", 1);
return str;
}
static VALUE
exc_backtrace(exc)
VALUE exc;
{
ID bt = rb_intern("bt");
if (!rb_ivar_defined(exc, bt)) return Qnil;
return rb_ivar_get(exc, bt);
}
static VALUE
check_backtrace(bt)
VALUE bt;
{
long 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;i<RARRAY(bt)->len;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;
VALUE bt;
{
return rb_iv_set(exc, "bt", check_backtrace(bt));
}
static VALUE
exit_status(exc)
VALUE exc;
{
return rb_iv_get(exc, "status");
}
* error.c (exc_exception): clone the receiver exception instead of creating brand new exception object of the receiver. * eval.c (rb_eval_string_wrap): extend new ruby_top_self, not original self. * eval.c (rb_eval_cmd): respect ruby_wrapper if set. * eval.c (eval): do not update ruby_class unless scope is not provided. * eval.c (eval): preserve wrapper information. * eval.c (proc_invoke): ditto. * eval.c (block_pass): ditto. * parse.y (void_expr): too much warnings for void context (e.g. foo[1] that can be mere Proc call). * error.c (rb_name_error): new function to raise NameError with name attribute set. * eval.c (rb_f_missing): set name and args in the exception object. [new] * error.c (name_name): NameError#name - new method. * error.c (nometh_args): NoMethodError#args - new method. * lex.c (rb_reserved_word): lex_state after tRESCUE should be EXPR_MID. * gc.c (add_heap): allocation size of the heap unit is doubled for each allocation. * dir.c (isdelim): space, tab, and newline are no longer delimiters for glob patterns. * eval.c (svalue_to_avalue): new conversion scheme between single value and array values. * eval.c (avalue_to_svalue): ditto. * eval.c (rb_eval): REXPAND now uses avalue_to_svalue(), return and yield too. * eval.c (rb_yield_0): use avalue_to_svalue(). * eval.c (proc_invoke): Proc#call gives avaules, whereas Proc#yield gives mvalues. * eval.c (bmcall): convert given value (svalue) to avalue. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1555 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2001-07-02 04:46:28 -04:00
void
#ifdef HAVE_STDARG_PROTOTYPES
rb_name_error(ID id, const char *fmt, ...)
#else
rb_name_error(id, fmt, va_alist)
ID id;
const char *fmt;
va_dcl
#endif
{
VALUE exc;
va_list args;
char buf[BUFSIZ];
va_init_list(args, fmt);
vsnprintf(buf, BUFSIZ, fmt, args);
va_end(args);
exc = rb_exc_new2(rb_eNameError, buf);
* error.c (exc_exception): clone the receiver exception instead of creating brand new exception object of the receiver. * eval.c (rb_eval_string_wrap): extend new ruby_top_self, not original self. * eval.c (rb_eval_cmd): respect ruby_wrapper if set. * eval.c (eval): do not update ruby_class unless scope is not provided. * eval.c (eval): preserve wrapper information. * eval.c (proc_invoke): ditto. * eval.c (block_pass): ditto. * parse.y (void_expr): too much warnings for void context (e.g. foo[1] that can be mere Proc call). * error.c (rb_name_error): new function to raise NameError with name attribute set. * eval.c (rb_f_missing): set name and args in the exception object. [new] * error.c (name_name): NameError#name - new method. * error.c (nometh_args): NoMethodError#args - new method. * lex.c (rb_reserved_word): lex_state after tRESCUE should be EXPR_MID. * gc.c (add_heap): allocation size of the heap unit is doubled for each allocation. * dir.c (isdelim): space, tab, and newline are no longer delimiters for glob patterns. * eval.c (svalue_to_avalue): new conversion scheme between single value and array values. * eval.c (avalue_to_svalue): ditto. * eval.c (rb_eval): REXPAND now uses avalue_to_svalue(), return and yield too. * eval.c (rb_yield_0): use avalue_to_svalue(). * eval.c (proc_invoke): Proc#call gives avaules, whereas Proc#yield gives mvalues. * eval.c (bmcall): convert given value (svalue) to avalue. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1555 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2001-07-02 04:46:28 -04:00
rb_iv_set(exc, "name", ID2SYM(id));
rb_exc_raise(exc);
}
static VALUE
name_err_name(self)
* error.c (exc_exception): clone the receiver exception instead of creating brand new exception object of the receiver. * eval.c (rb_eval_string_wrap): extend new ruby_top_self, not original self. * eval.c (rb_eval_cmd): respect ruby_wrapper if set. * eval.c (eval): do not update ruby_class unless scope is not provided. * eval.c (eval): preserve wrapper information. * eval.c (proc_invoke): ditto. * eval.c (block_pass): ditto. * parse.y (void_expr): too much warnings for void context (e.g. foo[1] that can be mere Proc call). * error.c (rb_name_error): new function to raise NameError with name attribute set. * eval.c (rb_f_missing): set name and args in the exception object. [new] * error.c (name_name): NameError#name - new method. * error.c (nometh_args): NoMethodError#args - new method. * lex.c (rb_reserved_word): lex_state after tRESCUE should be EXPR_MID. * gc.c (add_heap): allocation size of the heap unit is doubled for each allocation. * dir.c (isdelim): space, tab, and newline are no longer delimiters for glob patterns. * eval.c (svalue_to_avalue): new conversion scheme between single value and array values. * eval.c (avalue_to_svalue): ditto. * eval.c (rb_eval): REXPAND now uses avalue_to_svalue(), return and yield too. * eval.c (rb_yield_0): use avalue_to_svalue(). * eval.c (proc_invoke): Proc#call gives avaules, whereas Proc#yield gives mvalues. * eval.c (bmcall): convert given value (svalue) to avalue. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1555 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2001-07-02 04:46:28 -04:00
VALUE self;
{
return rb_iv_get(self, "name");
}
static VALUE
nometh_err_args(self)
* error.c (exc_exception): clone the receiver exception instead of creating brand new exception object of the receiver. * eval.c (rb_eval_string_wrap): extend new ruby_top_self, not original self. * eval.c (rb_eval_cmd): respect ruby_wrapper if set. * eval.c (eval): do not update ruby_class unless scope is not provided. * eval.c (eval): preserve wrapper information. * eval.c (proc_invoke): ditto. * eval.c (block_pass): ditto. * parse.y (void_expr): too much warnings for void context (e.g. foo[1] that can be mere Proc call). * error.c (rb_name_error): new function to raise NameError with name attribute set. * eval.c (rb_f_missing): set name and args in the exception object. [new] * error.c (name_name): NameError#name - new method. * error.c (nometh_args): NoMethodError#args - new method. * lex.c (rb_reserved_word): lex_state after tRESCUE should be EXPR_MID. * gc.c (add_heap): allocation size of the heap unit is doubled for each allocation. * dir.c (isdelim): space, tab, and newline are no longer delimiters for glob patterns. * eval.c (svalue_to_avalue): new conversion scheme between single value and array values. * eval.c (avalue_to_svalue): ditto. * eval.c (rb_eval): REXPAND now uses avalue_to_svalue(), return and yield too. * eval.c (rb_yield_0): use avalue_to_svalue(). * eval.c (proc_invoke): Proc#call gives avaules, whereas Proc#yield gives mvalues. * eval.c (bmcall): convert given value (svalue) to avalue. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1555 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2001-07-02 04:46:28 -04:00
VALUE self;
{
return rb_iv_get(self, "args");
}
void
rb_invalid_str(str, type)
const char *str, *type;
{
VALUE s = rb_str_inspect(rb_str_new2(str));
rb_raise(rb_eArgError, "invalid value for %s: %s", type, RSTRING(s)->ptr);
}
#ifdef __BEOS__
typedef struct {
VALUE *list;
int n;
} syserr_list_entry;
typedef struct {
int ix;
int n;
} syserr_index_entry;
static VALUE syserr_error;
static VALUE syserr_list_b_general[16+1];
static VALUE syserr_list_b_os0[2+1];
static VALUE syserr_list_b_os1[5+1];
static VALUE syserr_list_b_os2[2+1];
static VALUE syserr_list_b_os3[3+1];
static VALUE syserr_list_b_os4[1+1];
static VALUE syserr_list_b_app[15+1];
static VALUE syserr_list_b_interface[0+1];
static VALUE syserr_list_b_media[8+1];
static VALUE syserr_list_b_midi[0+1];
static VALUE syserr_list_b_storage[15+1];
static VALUE syserr_list_b_posix[38+1];
static VALUE syserr_list_b_mail[8+1];
static VALUE syserr_list_b_print[1+1];
static VALUE syserr_list_b_device[14+1];
# define SYSERR_LIST_B(n) {(n), sizeof(n)/sizeof(VALUE)}
static const syserr_list_entry syserr_list[] = {
SYSERR_LIST_B(syserr_list_b_general),
SYSERR_LIST_B(syserr_list_b_os0),
SYSERR_LIST_B(syserr_list_b_os1),
SYSERR_LIST_B(syserr_list_b_os2),
SYSERR_LIST_B(syserr_list_b_os3),
SYSERR_LIST_B(syserr_list_b_os4),
SYSERR_LIST_B(syserr_list_b_app),
SYSERR_LIST_B(syserr_list_b_interface),
SYSERR_LIST_B(syserr_list_b_media),
SYSERR_LIST_B(syserr_list_b_midi),
SYSERR_LIST_B(syserr_list_b_storage),
SYSERR_LIST_B(syserr_list_b_posix),
SYSERR_LIST_B(syserr_list_b_mail),
SYSERR_LIST_B(syserr_list_b_print),
SYSERR_LIST_B(syserr_list_b_device),
};
# undef SYSERR_LIST_B
static const syserr_index_entry syserr_index[]= {
{0, 1}, {1, 5}, {6, 1}, {7, 1}, {8, 1}, {9, 1}, {10, 1}, {11, 1},
{12, 1}, {13, 1}, {14, 1}, {0, 0},
};
#else
static VALUE *syserr_list;
#endif
#if !HAVE_DECL_SYS_NERR
extern int sys_nerr;
#endif
static VALUE
set_syserr(i, name)
int i;
const char *name;
{
#ifdef __BEOS__
VALUE *list;
int ix, offset;
#endif
VALUE error = rb_define_class_under(rb_mErrno, name, rb_eSystemCallError);
rb_define_const(error, "Errno", INT2NUM(i));
#ifdef __BEOS__
if (i == B_ERROR) {
syserr_error = error;
rb_global_variable(&syserr_error);
return error;
}
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;
list[i & 0xff] = error;
rb_global_variable(&list[i & 0xff]);
}
}
#else
if (i <= sys_nerr) {
syserr_list[i] = error;
}
#endif
return error;
}
static VALUE
syserr_errno(self)
VALUE self;
{
return rb_iv_get(self, "errno");
}
* eval.c (block_pass): should not downgrade safe level. * ext/dbm/extconf.rb: allow specifying dbm-type explicitly. * ext/dbm/extconf.rb: avoid gdbm if possible, because it leaks memory, whereas gdbm.so doesn't. potential incompatibility. * string.c (rb_str_insert): new method. * parse.y (yylex): lex_state after RESCUE_MOD should be EXPR_BEG. * array.c (rb_ary_insert): new method. * array.c (rb_ary_update): new utility function. * io.c (set_outfile): should check if closed before assignment. * eval.c (rb_eval): should preserve value of ruby_errinfo. * eval.c (rb_thread_schedule): infinite sleep should not cause dead lock. * array.c (rb_ary_flatten_bang): proper recursive detection. * eval.c (yield_under): need not to prohibit at safe level 4. * pack.c (pack_pack): p/P packs nil into NULL. * pack.c (pack_unpack): p/P unpacks NULL into nil. * pack.c (pack_pack): size check for P template. * ruby.c (set_arg0): wrong predicate when new $0 value is bigger than original space. * gc.c (id2ref): should use NUM2ULONG() * object.c (rb_mod_const_get): check whether name is a class variable name. * object.c (rb_mod_const_set): ditto. * object.c (rb_mod_const_defined): ditto. * marshal.c (w_float): precision changed to "%.16g" * eval.c (rb_call0): wrong retry behavior. * numeric.c (fix_aref): a bug on long>int architecture. * eval.c (rb_eval_string_wrap): should restore ruby_wrapper. * regex.c (re_compile_pattern): char class at either edge of range should be invalid. * eval.c (handle_rescue): use === to compare exception match. * error.c (syserr_eqq): comparison between SytemCallErrors should based on their error numbers. * eval.c (safe_getter): should use INT2NUM(). * bignum.c (rb_big2long): 2**31 cannot fit in 31 bit long. * regex.c (calculate_must_string): wrong length calculation. * eval.c (rb_thread_start_0): fixed memory leak. * parse.y (none): should clear cmdarg_stack too. * io.c (rb_fopen): use setvbuf() to avoid recursive malloc() on some platforms. * file.c (rb_stat_dev): device functions should honor stat field types (except long long such as dev_t). * eval.c (rb_mod_nesting): should not push nil for nesting array. * eval.c (rb_mod_s_constants): should not search array by rb_mod_const_at() for nil (happens for singleton class). * class.c (rb_singleton_class_attached): should modify iv_tbl by itself, no longer use rb_iv_set() to avoid freeze check error. * variable.c (rb_const_get): error message "uninitialized constant Foo at Bar::Baz" instead of "uninitialized constantBar::Baz::Foo". * eval.c (rb_mod_included): new hook called from rb_mod_include(). * io.c (opt_i_set): should strdup() inplace_edit string. * eval.c (exec_under): need to push cref too. * eval.c (rb_f_missing): raise NameError for "undefined local variable or method". * error.c (Init_Exception): new exception NoMethodError. NameError moved under ScriptError again. * eval.c (rb_f_missing): use NoMethodError instead of NameError. * file.c (Init_File): should redifine "new" class method. * eval.c (PUSH_CREF): sharing cref node was problematic. maintain runtime cref list instead. * eval.c (rb_eval): copy defn node before registering. * eval.c (rb_load): clear ruby_cref before loading. * variable.c (rb_const_get): no recursion to show full class path for modules. * eval.c (rb_set_safe_level): should set safe level in curr_thread as well. * eval.c (safe_setter): ditto. * object.c (rb_obj_is_instance_of): nil belongs to false, not true. * time.c (make_time_t): proper (I hope) daylight saving time handling for both US and Europe. I HATE DST! * eval.c (rb_thread_wait_for): non blocked signal interrupt should stop the interval. * eval.c (proc_eq): class check aded. * eval.c (proc_eq): typo fixed ("return" was ommitted). * error.c (Init_Exception): move NameError under StandardError. * class.c (rb_mod_clone): should copy method bodies too. * bignum.c (bigdivrem): should trim trailing zero bdigits of remainder, even if dd == 0. * file.c (check3rdbyte): safe string check moved here. * time.c (make_time_t): remove HAVE_TM_ZONE code since it sometimes reports wrong time. * time.c (make_time_t): remove unnecessary range check for platforms where negative time_t is available. * process.c (proc_waitall): should push Process::Status instead of Finuxm status. * process.c (waitall_each): should add all entries in pid_tbl. these changes are inspired by Koji Arai. Thanks. * process.c (proc_wait): should not iterate if pid_tbl is 0. * process.c (proc_waitall): ditto. * numeric.c (flodivmod): a bug in no fmod case. * process.c (pst_wifsignaled): should apply WIFSIGNALED for status (int), not st (VALUE). * io.c (Init_IO): value of $/ and $\ are no longer restricted to strings. type checks are done on demand. * class.c (rb_include_module): module inclusion should be check taints. * ruby.h (STR2CSTR): replace to StringType() and StringTypePtr(). * ruby.h (rb_str2cstr): ditto. * eval.c (rb_load): should not copy topleve local variables. It cause variable/method ambiguity. Thanks to L. Peter Deutsch. * class.c (rb_include_module): freeze check at first. * eval.c (rb_attr): sprintf() and rb_intern() moved into conditional body. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1356 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2001-05-02 00:22:21 -04:00
static VALUE
syserr_eqq(self, exc)
VALUE self, exc;
{
VALUE num;
if (!rb_obj_is_kind_of(exc, rb_eSystemCallError)) return Qfalse;
if (self == rb_eSystemCallError) return Qtrue;
num = rb_iv_get(exc, "errno");
if (NIL_P(num)) {
VALUE klass = CLASS_OF(exc);
while (TYPE(klass) == T_ICLASS || FL_TEST(klass, FL_SINGLETON)) {
klass = (VALUE)RCLASS(klass)->super;
}
num = rb_const_get(klass, rb_intern("Errno"));
}
if (rb_const_get(self, rb_intern("Errno")) == num)
return Qtrue;
return Qfalse;
}
#ifdef __BEOS__
static VALUE
get_syserr(int i)
{
VALUE *list;
int ix, offset;
if (i == B_ERROR) return syserr_error;
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()
{
rb_eException = rb_define_class("Exception", rb_cObject);
rb_define_singleton_method(rb_eException, "exception", rb_class_new_instance, -1);
rb_define_method(rb_eException, "exception", exc_exception, -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_define_method(rb_eSystemExit, "status", exit_status, 0);
rb_eFatal = rb_define_class("fatal", rb_eException);
rb_eSignal = rb_define_class("SignalException", rb_eException);
rb_eInterrupt = rb_define_class("Interrupt", rb_eSignal);
rb_eStandardError = rb_define_class("StandardError", rb_eException);
* eval.c (block_pass): should not downgrade safe level. * ext/dbm/extconf.rb: allow specifying dbm-type explicitly. * ext/dbm/extconf.rb: avoid gdbm if possible, because it leaks memory, whereas gdbm.so doesn't. potential incompatibility. * string.c (rb_str_insert): new method. * parse.y (yylex): lex_state after RESCUE_MOD should be EXPR_BEG. * array.c (rb_ary_insert): new method. * array.c (rb_ary_update): new utility function. * io.c (set_outfile): should check if closed before assignment. * eval.c (rb_eval): should preserve value of ruby_errinfo. * eval.c (rb_thread_schedule): infinite sleep should not cause dead lock. * array.c (rb_ary_flatten_bang): proper recursive detection. * eval.c (yield_under): need not to prohibit at safe level 4. * pack.c (pack_pack): p/P packs nil into NULL. * pack.c (pack_unpack): p/P unpacks NULL into nil. * pack.c (pack_pack): size check for P template. * ruby.c (set_arg0): wrong predicate when new $0 value is bigger than original space. * gc.c (id2ref): should use NUM2ULONG() * object.c (rb_mod_const_get): check whether name is a class variable name. * object.c (rb_mod_const_set): ditto. * object.c (rb_mod_const_defined): ditto. * marshal.c (w_float): precision changed to "%.16g" * eval.c (rb_call0): wrong retry behavior. * numeric.c (fix_aref): a bug on long>int architecture. * eval.c (rb_eval_string_wrap): should restore ruby_wrapper. * regex.c (re_compile_pattern): char class at either edge of range should be invalid. * eval.c (handle_rescue): use === to compare exception match. * error.c (syserr_eqq): comparison between SytemCallErrors should based on their error numbers. * eval.c (safe_getter): should use INT2NUM(). * bignum.c (rb_big2long): 2**31 cannot fit in 31 bit long. * regex.c (calculate_must_string): wrong length calculation. * eval.c (rb_thread_start_0): fixed memory leak. * parse.y (none): should clear cmdarg_stack too. * io.c (rb_fopen): use setvbuf() to avoid recursive malloc() on some platforms. * file.c (rb_stat_dev): device functions should honor stat field types (except long long such as dev_t). * eval.c (rb_mod_nesting): should not push nil for nesting array. * eval.c (rb_mod_s_constants): should not search array by rb_mod_const_at() for nil (happens for singleton class). * class.c (rb_singleton_class_attached): should modify iv_tbl by itself, no longer use rb_iv_set() to avoid freeze check error. * variable.c (rb_const_get): error message "uninitialized constant Foo at Bar::Baz" instead of "uninitialized constantBar::Baz::Foo". * eval.c (rb_mod_included): new hook called from rb_mod_include(). * io.c (opt_i_set): should strdup() inplace_edit string. * eval.c (exec_under): need to push cref too. * eval.c (rb_f_missing): raise NameError for "undefined local variable or method". * error.c (Init_Exception): new exception NoMethodError. NameError moved under ScriptError again. * eval.c (rb_f_missing): use NoMethodError instead of NameError. * file.c (Init_File): should redifine "new" class method. * eval.c (PUSH_CREF): sharing cref node was problematic. maintain runtime cref list instead. * eval.c (rb_eval): copy defn node before registering. * eval.c (rb_load): clear ruby_cref before loading. * variable.c (rb_const_get): no recursion to show full class path for modules. * eval.c (rb_set_safe_level): should set safe level in curr_thread as well. * eval.c (safe_setter): ditto. * object.c (rb_obj_is_instance_of): nil belongs to false, not true. * time.c (make_time_t): proper (I hope) daylight saving time handling for both US and Europe. I HATE DST! * eval.c (rb_thread_wait_for): non blocked signal interrupt should stop the interval. * eval.c (proc_eq): class check aded. * eval.c (proc_eq): typo fixed ("return" was ommitted). * error.c (Init_Exception): move NameError under StandardError. * class.c (rb_mod_clone): should copy method bodies too. * bignum.c (bigdivrem): should trim trailing zero bdigits of remainder, even if dd == 0. * file.c (check3rdbyte): safe string check moved here. * time.c (make_time_t): remove HAVE_TM_ZONE code since it sometimes reports wrong time. * time.c (make_time_t): remove unnecessary range check for platforms where negative time_t is available. * process.c (proc_waitall): should push Process::Status instead of Finuxm status. * process.c (waitall_each): should add all entries in pid_tbl. these changes are inspired by Koji Arai. Thanks. * process.c (proc_wait): should not iterate if pid_tbl is 0. * process.c (proc_waitall): ditto. * numeric.c (flodivmod): a bug in no fmod case. * process.c (pst_wifsignaled): should apply WIFSIGNALED for status (int), not st (VALUE). * io.c (Init_IO): value of $/ and $\ are no longer restricted to strings. type checks are done on demand. * class.c (rb_include_module): module inclusion should be check taints. * ruby.h (STR2CSTR): replace to StringType() and StringTypePtr(). * ruby.h (rb_str2cstr): ditto. * eval.c (rb_load): should not copy topleve local variables. It cause variable/method ambiguity. Thanks to L. Peter Deutsch. * class.c (rb_include_module): freeze check at first. * eval.c (rb_attr): sprintf() and rb_intern() moved into conditional body. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1356 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2001-05-02 00:22:21 -04:00
rb_eTypeError = rb_define_class("TypeError", rb_eStandardError);
rb_eArgError = rb_define_class("ArgumentError", rb_eStandardError);
rb_eIndexError = rb_define_class("IndexError", rb_eStandardError);
rb_eRangeError = rb_define_class("RangeError", rb_eStandardError);
rb_eNameError = rb_define_class("NameError", rb_eStandardError);
rb_define_method(rb_eNameError, "name", name_err_name, 0);
rb_eNoMethodError = rb_define_class("NoMethodError", rb_eNameError);
rb_define_method(rb_eNoMethodError, "args", nometh_err_args, 0);
rb_eScriptError = rb_define_class("ScriptError", rb_eException);
rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError);
rb_eLoadError = rb_define_class("LoadError", rb_eScriptError);
rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError);
rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError);
rb_eSecurityError = rb_define_class("SecurityError", rb_eStandardError);
rb_eNoMemError = rb_define_class("NoMemoryError", rb_eException);
init_syserr();
}
void
#ifdef HAVE_STDARG_PROTOTYPES
rb_raise(VALUE exc, const char *fmt, ...)
#else
rb_raise(exc, fmt, va_alist)
VALUE exc;
const char *fmt;
va_dcl
#endif
{
va_list args;
char buf[BUFSIZ];
va_init_list(args,fmt);
vsnprintf(buf, BUFSIZ, fmt, args);
va_end(args);
rb_exc_raise(rb_exc_new2(exc, buf));
}
void
#ifdef HAVE_STDARG_PROTOTYPES
rb_loaderror(const char *fmt, ...)
#else
rb_loaderror(fmt, va_alist)
const char *fmt;
va_dcl
#endif
{
va_list args;
char buf[BUFSIZ];
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()
{
rb_raise(rb_eNotImpError,
"The %s() function is unimplemented on this machine",
rb_id2name(ruby_frame->last_func));
}
void
#ifdef HAVE_STDARG_PROTOTYPES
rb_fatal(const char *fmt, ...)
#else
rb_fatal(fmt, va_alist)
const char *fmt;
va_dcl
#endif
{
va_list args;
char buf[BUFSIZ];
va_init_list(args, fmt);
vsnprintf(buf, BUFSIZ, fmt, args);
va_end(args);
ruby_in_eval = 0;
rb_exc_fatal(rb_exc_new2(rb_eFatal, buf));
}
void
rb_sys_fail(mesg)
const char *mesg;
{
#if !defined(NT) && !defined(__VMS)
char *strerror();
#endif
char *err;
char *buf;
extern int errno;
int n = errno;
VALUE ee;
* array.c (rb_ary_modify): should copy the internal buffer if the modifying buffer is shared. * array.c (ary_make_shared): make an internal buffer of an array to be shared. * array.c (rb_ary_shift): avoid sliding an internal buffer by using shared buffer. * array.c (rb_ary_subseq): avoid copying the buffer. * parse.y (gettable): should freeze __LINE__ string. * io.c (rb_io_puts): old behavoir restored. rationale: a) if you want to call to_s for arrays, you can just call print a, "\n". b) to_s wastes memory if array (and sum of its contents) is huge. c) now any object that has to_ary is treated as an array, using rb_check_convert_type(). * hash.c (rb_hash_initialize): now accepts a block to calculate the default value. [new] * hash.c (rb_hash_aref): call "default" method to get the value corrensponding to the non existing key. * hash.c (rb_hash_default): get the default value based on the block given to 'new'. Now it takes an optinal "key" argument. "default" became the method to get the value for non existing key. Users may override "default" method to change the hash behavior. * hash.c (rb_hash_set_default): clear the flag if a block is given to 'new' * object.c (Init_Object): undef Data.allocate, left Data.new. * ext/curses/curses.c (window_scrollok): use RTEST(). * ext/curses/curses.c (window_idlok): ditto. * ext/curses/curses.c (window_keypad): ditto. * ext/curses/curses.c (window_idlok): idlok() may return void on some platforms; so don't use return value. * ext/curses/curses.c (window_scrollok): ditto for consistency. * ext/curses/curses.c: replace FIX2INT() by typechecking NUM2INT(). * parse.y (str_extend): should not process immature #$x and #@x interpolation, e.g #@#@ etc. * enum.c (enum_sort_by): sort_by does not have to be stable always. * enum.c (enum_sort_by): call qsort directly to gain performance. * util.c (ruby_qsort): ruby_qsort(qs6) is now native thread safe. * error.c (rb_sys_fail): it must be a bug if it's called when errno == 0. * regex.c (WC2MBC1ST): should not pass through > 0x80 number in UTF-8. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1896 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2001-12-10 02:18:16 -05:00
if (errno == 0) {
rb_bug("rb_sys_fail() - errno == 0");
}
#ifdef __BORLANDC__
if (errno == EPIPE) return; // (*moriq*)
#endif
err = strerror(errno);
if (mesg) {
volatile VALUE tmp = rb_str_inspect(rb_str_new2(mesg));
buf = ALLOCA_N(char, strlen(err)+RSTRING(tmp)->len+4);
sprintf(buf, "%s - %s", err, RSTRING(tmp)->ptr);
}
else {
buf = ALLOCA_N(char, strlen(err)+1);
strcpy(buf, err);
}
errno = 0;
#ifdef __BEOS__
ee = get_syserr(n);
if (!ee) {
char name[12];
sprintf(name, "E%03d", n);
ee = set_syserr(n, name);
}
#else
if (n > sys_nerr || !syserr_list[n]) {
char name[12];
sprintf(name, "E%03d", n);
ee = set_syserr(n, name);
}
else {
ee = syserr_list[n];
}
#endif
ee = rb_exc_new2(ee, buf);
rb_iv_set(ee, "errno", INT2NUM(n));
rb_exc_raise(ee);
}
void
#ifdef HAVE_STDARG_PROTOTYPES
rb_sys_warning(const char *fmt, ...)
#else
rb_sys_warning(fmt, va_alist)
const char *fmt;
va_dcl
#endif
{
char buf[BUFSIZ];
va_list args;
int errno_save;
errno_save = errno;
if (!RTEST(ruby_verbose)) return;
snprintf(buf, BUFSIZ, "warning: %s", fmt);
snprintf(buf+strlen(buf), BUFSIZ-strlen(buf), ": %s", strerror(errno_save));
va_init_list(args, fmt);
warn_print(buf, args);
va_end(args);
errno = errno_save;
}
void
rb_load_fail(path)
char *path;
{
rb_loaderror("%s -- %s", strerror(errno), path);
}
void
rb_error_frozen(what)
char *what;
{
rb_raise(rb_eTypeError, "can't modify frozen %s", what);
}
void
rb_check_frozen(obj)
VALUE obj;
{
if (OBJ_FROZEN(obj)) rb_error_frozen(rb_class2name(CLASS_OF(obj)));
}
static void
init_syserr()
{
#ifdef __BEOS__
int i, ix, offset;
#endif
rb_eSystemCallError = rb_define_class("SystemCallError", rb_eStandardError);
rb_define_method(rb_eSystemCallError, "errno", syserr_errno, 0);
* eval.c (block_pass): should not downgrade safe level. * ext/dbm/extconf.rb: allow specifying dbm-type explicitly. * ext/dbm/extconf.rb: avoid gdbm if possible, because it leaks memory, whereas gdbm.so doesn't. potential incompatibility. * string.c (rb_str_insert): new method. * parse.y (yylex): lex_state after RESCUE_MOD should be EXPR_BEG. * array.c (rb_ary_insert): new method. * array.c (rb_ary_update): new utility function. * io.c (set_outfile): should check if closed before assignment. * eval.c (rb_eval): should preserve value of ruby_errinfo. * eval.c (rb_thread_schedule): infinite sleep should not cause dead lock. * array.c (rb_ary_flatten_bang): proper recursive detection. * eval.c (yield_under): need not to prohibit at safe level 4. * pack.c (pack_pack): p/P packs nil into NULL. * pack.c (pack_unpack): p/P unpacks NULL into nil. * pack.c (pack_pack): size check for P template. * ruby.c (set_arg0): wrong predicate when new $0 value is bigger than original space. * gc.c (id2ref): should use NUM2ULONG() * object.c (rb_mod_const_get): check whether name is a class variable name. * object.c (rb_mod_const_set): ditto. * object.c (rb_mod_const_defined): ditto. * marshal.c (w_float): precision changed to "%.16g" * eval.c (rb_call0): wrong retry behavior. * numeric.c (fix_aref): a bug on long>int architecture. * eval.c (rb_eval_string_wrap): should restore ruby_wrapper. * regex.c (re_compile_pattern): char class at either edge of range should be invalid. * eval.c (handle_rescue): use === to compare exception match. * error.c (syserr_eqq): comparison between SytemCallErrors should based on their error numbers. * eval.c (safe_getter): should use INT2NUM(). * bignum.c (rb_big2long): 2**31 cannot fit in 31 bit long. * regex.c (calculate_must_string): wrong length calculation. * eval.c (rb_thread_start_0): fixed memory leak. * parse.y (none): should clear cmdarg_stack too. * io.c (rb_fopen): use setvbuf() to avoid recursive malloc() on some platforms. * file.c (rb_stat_dev): device functions should honor stat field types (except long long such as dev_t). * eval.c (rb_mod_nesting): should not push nil for nesting array. * eval.c (rb_mod_s_constants): should not search array by rb_mod_const_at() for nil (happens for singleton class). * class.c (rb_singleton_class_attached): should modify iv_tbl by itself, no longer use rb_iv_set() to avoid freeze check error. * variable.c (rb_const_get): error message "uninitialized constant Foo at Bar::Baz" instead of "uninitialized constantBar::Baz::Foo". * eval.c (rb_mod_included): new hook called from rb_mod_include(). * io.c (opt_i_set): should strdup() inplace_edit string. * eval.c (exec_under): need to push cref too. * eval.c (rb_f_missing): raise NameError for "undefined local variable or method". * error.c (Init_Exception): new exception NoMethodError. NameError moved under ScriptError again. * eval.c (rb_f_missing): use NoMethodError instead of NameError. * file.c (Init_File): should redifine "new" class method. * eval.c (PUSH_CREF): sharing cref node was problematic. maintain runtime cref list instead. * eval.c (rb_eval): copy defn node before registering. * eval.c (rb_load): clear ruby_cref before loading. * variable.c (rb_const_get): no recursion to show full class path for modules. * eval.c (rb_set_safe_level): should set safe level in curr_thread as well. * eval.c (safe_setter): ditto. * object.c (rb_obj_is_instance_of): nil belongs to false, not true. * time.c (make_time_t): proper (I hope) daylight saving time handling for both US and Europe. I HATE DST! * eval.c (rb_thread_wait_for): non blocked signal interrupt should stop the interval. * eval.c (proc_eq): class check aded. * eval.c (proc_eq): typo fixed ("return" was ommitted). * error.c (Init_Exception): move NameError under StandardError. * class.c (rb_mod_clone): should copy method bodies too. * bignum.c (bigdivrem): should trim trailing zero bdigits of remainder, even if dd == 0. * file.c (check3rdbyte): safe string check moved here. * time.c (make_time_t): remove HAVE_TM_ZONE code since it sometimes reports wrong time. * time.c (make_time_t): remove unnecessary range check for platforms where negative time_t is available. * process.c (proc_waitall): should push Process::Status instead of Finuxm status. * process.c (waitall_each): should add all entries in pid_tbl. these changes are inspired by Koji Arai. Thanks. * process.c (proc_wait): should not iterate if pid_tbl is 0. * process.c (proc_waitall): ditto. * numeric.c (flodivmod): a bug in no fmod case. * process.c (pst_wifsignaled): should apply WIFSIGNALED for status (int), not st (VALUE). * io.c (Init_IO): value of $/ and $\ are no longer restricted to strings. type checks are done on demand. * class.c (rb_include_module): module inclusion should be check taints. * ruby.h (STR2CSTR): replace to StringType() and StringTypePtr(). * ruby.h (rb_str2cstr): ditto. * eval.c (rb_load): should not copy topleve local variables. It cause variable/method ambiguity. Thanks to L. Peter Deutsch. * class.c (rb_include_module): freeze check at first. * eval.c (rb_attr): sprintf() and rb_intern() moved into conditional body. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1356 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2001-05-02 00:22:21 -04:00
rb_define_singleton_method(rb_eSystemCallError, "===", syserr_eqq, 1);
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);
}
}
set_syserr(B_ERROR, "ERROR");
#else
syserr_list = ALLOC_N(VALUE, sys_nerr+1);
MEMZERO(syserr_list, VALUE, sys_nerr+1);
#endif
#ifdef EPERM
set_syserr(EPERM, "EPERM");
#endif
#ifdef ENOENT
set_syserr(ENOENT, "ENOENT");
#endif
#ifdef ESRCH
set_syserr(ESRCH, "ESRCH");
#endif
#ifdef EINTR
set_syserr(EINTR, "EINTR");
#endif
#ifdef EIO
set_syserr(EIO, "EIO");
#endif
#ifdef ENXIO
set_syserr(ENXIO, "ENXIO");
#endif
#ifdef E2BIG
set_syserr(E2BIG, "E2BIG");
#endif
#ifdef ENOEXEC
set_syserr(ENOEXEC, "ENOEXEC");
#endif
#ifdef EBADF
set_syserr(EBADF, "EBADF");
#endif
#ifdef ECHILD
set_syserr(ECHILD, "ECHILD");
#endif
#ifdef EAGAIN
set_syserr(EAGAIN, "EAGAIN");
#endif
#ifdef ENOMEM
set_syserr(ENOMEM, "ENOMEM");
#endif
#ifdef EACCES
set_syserr(EACCES, "EACCES");
#endif
#ifdef EFAULT
set_syserr(EFAULT, "EFAULT");
#endif
#ifdef ENOTBLK
set_syserr(ENOTBLK, "ENOTBLK");
#endif
#ifdef EBUSY
set_syserr(EBUSY, "EBUSY");
#endif
#ifdef EEXIST
set_syserr(EEXIST, "EEXIST");
#endif
#ifdef EXDEV
set_syserr(EXDEV, "EXDEV");
#endif
#ifdef ENODEV
set_syserr(ENODEV, "ENODEV");
#endif
#ifdef ENOTDIR
set_syserr(ENOTDIR, "ENOTDIR");
#endif
#ifdef EISDIR
set_syserr(EISDIR, "EISDIR");
#endif
#ifdef EINVAL
set_syserr(EINVAL, "EINVAL");
#endif
#ifdef ENFILE
set_syserr(ENFILE, "ENFILE");
#endif
#ifdef EMFILE
set_syserr(EMFILE, "EMFILE");
#endif
#ifdef ENOTTY
set_syserr(ENOTTY, "ENOTTY");
#endif
#ifdef ETXTBSY
set_syserr(ETXTBSY, "ETXTBSY");
#endif
#ifdef EFBIG
set_syserr(EFBIG, "EFBIG");
#endif
#ifdef ENOSPC
set_syserr(ENOSPC, "ENOSPC");
#endif
#ifdef ESPIPE
set_syserr(ESPIPE, "ESPIPE");
#endif
#ifdef EROFS
set_syserr(EROFS, "EROFS");
#endif
#ifdef EMLINK
set_syserr(EMLINK, "EMLINK");
#endif
#ifdef EPIPE
set_syserr(EPIPE, "EPIPE");
#endif
#ifdef EDOM
set_syserr(EDOM, "EDOM");
#endif
#ifdef ERANGE
set_syserr(ERANGE, "ERANGE");
#endif
#ifdef EDEADLK
set_syserr(EDEADLK, "EDEADLK");
#endif
#ifdef ENAMETOOLONG
set_syserr(ENAMETOOLONG, "ENAMETOOLONG");
#endif
#ifdef ENOLCK
set_syserr(ENOLCK, "ENOLCK");
#endif
#ifdef ENOSYS
set_syserr(ENOSYS, "ENOSYS");
#endif
#ifdef ENOTEMPTY
set_syserr(ENOTEMPTY, "ENOTEMPTY");
#endif
#ifdef ELOOP
set_syserr(ELOOP, "ELOOP");
#endif
#ifdef EWOULDBLOCK
set_syserr(EWOULDBLOCK, "EWOULDBLOCK");
#endif
#ifdef ENOMSG
set_syserr(ENOMSG, "ENOMSG");
#endif
#ifdef EIDRM
set_syserr(EIDRM, "EIDRM");
#endif
#ifdef ECHRNG
set_syserr(ECHRNG, "ECHRNG");
#endif
#ifdef EL2NSYNC
set_syserr(EL2NSYNC, "EL2NSYNC");
#endif
#ifdef EL3HLT
set_syserr(EL3HLT, "EL3HLT");
#endif
#ifdef EL3RST
set_syserr(EL3RST, "EL3RST");
#endif
#ifdef ELNRNG
set_syserr(ELNRNG, "ELNRNG");
#endif
#ifdef EUNATCH
set_syserr(EUNATCH, "EUNATCH");
#endif
#ifdef ENOCSI
set_syserr(ENOCSI, "ENOCSI");
#endif
#ifdef EL2HLT
set_syserr(EL2HLT, "EL2HLT");
#endif
#ifdef EBADE
set_syserr(EBADE, "EBADE");
#endif
#ifdef EBADR
set_syserr(EBADR, "EBADR");
#endif
#ifdef EXFULL
set_syserr(EXFULL, "EXFULL");
#endif
#ifdef ENOANO
set_syserr(ENOANO, "ENOANO");
#endif
#ifdef EBADRQC
set_syserr(EBADRQC, "EBADRQC");
#endif
#ifdef EBADSLT
set_syserr(EBADSLT, "EBADSLT");
#endif
#ifdef EDEADLOCK
set_syserr(EDEADLOCK, "EDEADLOCK");
#endif
#ifdef EBFONT
set_syserr(EBFONT, "EBFONT");
#endif
#ifdef ENOSTR
set_syserr(ENOSTR, "ENOSTR");
#endif
#ifdef ENODATA
set_syserr(ENODATA, "ENODATA");
#endif
#ifdef ETIME
set_syserr(ETIME, "ETIME");
#endif
#ifdef ENOSR
set_syserr(ENOSR, "ENOSR");
#endif
#ifdef ENONET
set_syserr(ENONET, "ENONET");
#endif
#ifdef ENOPKG
set_syserr(ENOPKG, "ENOPKG");
#endif
#ifdef EREMOTE
set_syserr(EREMOTE, "EREMOTE");
#endif
#ifdef ENOLINK
set_syserr(ENOLINK, "ENOLINK");
#endif
#ifdef EADV
set_syserr(EADV, "EADV");
#endif
#ifdef ESRMNT
set_syserr(ESRMNT, "ESRMNT");
#endif
#ifdef ECOMM
set_syserr(ECOMM, "ECOMM");
#endif
#ifdef EPROTO
set_syserr(EPROTO, "EPROTO");
#endif
#ifdef EMULTIHOP
set_syserr(EMULTIHOP, "EMULTIHOP");
#endif
#ifdef EDOTDOT
set_syserr(EDOTDOT, "EDOTDOT");
#endif
#ifdef EBADMSG
set_syserr(EBADMSG, "EBADMSG");
#endif
#ifdef EOVERFLOW
set_syserr(EOVERFLOW, "EOVERFLOW");
#endif
#ifdef ENOTUNIQ
set_syserr(ENOTUNIQ, "ENOTUNIQ");
#endif
#ifdef EBADFD
set_syserr(EBADFD, "EBADFD");
#endif
#ifdef EREMCHG
set_syserr(EREMCHG, "EREMCHG");
#endif
#ifdef ELIBACC
set_syserr(ELIBACC, "ELIBACC");
#endif
#ifdef ELIBBAD
set_syserr(ELIBBAD, "ELIBBAD");
#endif
#ifdef ELIBSCN
set_syserr(ELIBSCN, "ELIBSCN");
#endif
#ifdef ELIBMAX
set_syserr(ELIBMAX, "ELIBMAX");
#endif
#ifdef ELIBEXEC
set_syserr(ELIBEXEC, "ELIBEXEC");
#endif
#ifdef EILSEQ
set_syserr(EILSEQ, "EILSEQ");
#endif
#ifdef ERESTART
set_syserr(ERESTART, "ERESTART");
#endif
#ifdef ESTRPIPE
set_syserr(ESTRPIPE, "ESTRPIPE");
#endif
#ifdef EUSERS
set_syserr(EUSERS, "EUSERS");
#endif
#ifdef ENOTSOCK
set_syserr(ENOTSOCK, "ENOTSOCK");
#endif
#ifdef EDESTADDRREQ
set_syserr(EDESTADDRREQ, "EDESTADDRREQ");
#endif
#ifdef EMSGSIZE
set_syserr(EMSGSIZE, "EMSGSIZE");
#endif
#ifdef EPROTOTYPE
set_syserr(EPROTOTYPE, "EPROTOTYPE");
#endif
#ifdef ENOPROTOOPT
set_syserr(ENOPROTOOPT, "ENOPROTOOPT");
#endif
#ifdef EPROTONOSUPPORT
set_syserr(EPROTONOSUPPORT, "EPROTONOSUPPORT");
#endif
#ifdef ESOCKTNOSUPPORT
set_syserr(ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT");
#endif
#ifdef EOPNOTSUPP
set_syserr(EOPNOTSUPP, "EOPNOTSUPP");
#endif
#ifdef EPFNOSUPPORT
set_syserr(EPFNOSUPPORT, "EPFNOSUPPORT");
#endif
#ifdef EAFNOSUPPORT
set_syserr(EAFNOSUPPORT, "EAFNOSUPPORT");
#endif
#ifdef EADDRINUSE
set_syserr(EADDRINUSE, "EADDRINUSE");
#endif
#ifdef EADDRNOTAVAIL
set_syserr(EADDRNOTAVAIL, "EADDRNOTAVAIL");
#endif
#ifdef ENETDOWN
set_syserr(ENETDOWN, "ENETDOWN");
#endif
#ifdef ENETUNREACH
set_syserr(ENETUNREACH, "ENETUNREACH");
#endif
#ifdef ENETRESET
set_syserr(ENETRESET, "ENETRESET");
#endif
#ifdef ECONNABORTED
set_syserr(ECONNABORTED, "ECONNABORTED");
#endif
#ifdef ECONNRESET
set_syserr(ECONNRESET, "ECONNRESET");
#endif
#ifdef ENOBUFS
set_syserr(ENOBUFS, "ENOBUFS");
#endif
#ifdef EISCONN
set_syserr(EISCONN, "EISCONN");
#endif
#ifdef ENOTCONN
set_syserr(ENOTCONN, "ENOTCONN");
#endif
#ifdef ESHUTDOWN
set_syserr(ESHUTDOWN, "ESHUTDOWN");
#endif
#ifdef ETOOMANYREFS
set_syserr(ETOOMANYREFS, "ETOOMANYREFS");
#endif
#ifdef ETIMEDOUT
set_syserr(ETIMEDOUT, "ETIMEDOUT");
#endif
#ifdef ECONNREFUSED
set_syserr(ECONNREFUSED, "ECONNREFUSED");
#endif
#ifdef EHOSTDOWN
set_syserr(EHOSTDOWN, "EHOSTDOWN");
#endif
#ifdef EHOSTUNREACH
set_syserr(EHOSTUNREACH, "EHOSTUNREACH");
#endif
#ifdef EALREADY
set_syserr(EALREADY, "EALREADY");
#endif
#ifdef EINPROGRESS
set_syserr(EINPROGRESS, "EINPROGRESS");
#endif
#ifdef ESTALE
set_syserr(ESTALE, "ESTALE");
#endif
#ifdef EUCLEAN
set_syserr(EUCLEAN, "EUCLEAN");
#endif
#ifdef ENOTNAM
set_syserr(ENOTNAM, "ENOTNAM");
#endif
#ifdef ENAVAIL
set_syserr(ENAVAIL, "ENAVAIL");
#endif
#ifdef EISNAM
set_syserr(EISNAM, "EISNAM");
#endif
#ifdef EREMOTEIO
set_syserr(EREMOTEIO, "EREMOTEIO");
#endif
#ifdef EDQUOT
set_syserr(EDQUOT, "EDQUOT");
#endif
}
static void
err_append(s)
const char *s;
{
extern VALUE ruby_errinfo;
if (ruby_in_eval) {
if (NIL_P(ruby_errinfo)) {
ruby_errinfo = rb_exc_new2(rb_eSyntaxError, s);
}
else {
VALUE str = rb_str_to_str(ruby_errinfo);
rb_str_cat2(str, "\n");
rb_str_cat2(str, s);
ruby_errinfo = rb_exc_new3(rb_eSyntaxError, str);
}
}
else {
fputs(s, stderr);
fputs("\n", stderr);
fflush(stderr);
}
}