Ruby
2.0.0p247(2013-06-27revision41674)
|
00001 /********************************************************************** 00002 00003 error.c - 00004 00005 $Author: nagachika $ 00006 created at: Mon Aug 9 16:11:34 JST 1993 00007 00008 Copyright (C) 1993-2007 Yukihiro Matsumoto 00009 00010 **********************************************************************/ 00011 00012 #include "ruby/ruby.h" 00013 #include "ruby/st.h" 00014 #include "ruby/encoding.h" 00015 #include "internal.h" 00016 #include "vm_core.h" 00017 00018 #include <stdio.h> 00019 #include <stdarg.h> 00020 #ifdef HAVE_STDLIB_H 00021 #include <stdlib.h> 00022 #endif 00023 #include <errno.h> 00024 #ifdef HAVE_UNISTD_H 00025 #include <unistd.h> 00026 #endif 00027 00028 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0])) 00029 00030 #ifndef EXIT_SUCCESS 00031 #define EXIT_SUCCESS 0 00032 #endif 00033 00034 #ifndef WIFEXITED 00035 #define WIFEXITED(status) 1 00036 #endif 00037 00038 #ifndef WEXITSTATUS 00039 #define WEXITSTATUS(status) (status) 00040 #endif 00041 00042 extern const char ruby_description[]; 00043 00044 #define REPORTBUG_MSG \ 00045 "[NOTE]\n" \ 00046 "You may have encountered a bug in the Ruby interpreter" \ 00047 " or extension libraries.\n" \ 00048 "Bug reports are welcome.\n" \ 00049 "For details: http://www.ruby-lang.org/bugreport.html\n\n" \ 00050 00051 static const char * 00052 rb_strerrno(int err) 00053 { 00054 #define defined_error(name, num) if (err == (num)) return (name); 00055 #define undefined_error(name) 00056 #include "known_errors.inc" 00057 #undef defined_error 00058 #undef undefined_error 00059 return NULL; 00060 } 00061 00062 static int 00063 err_position_0(char *buf, long len, const char *file, int line) 00064 { 00065 if (!file) { 00066 return 0; 00067 } 00068 else if (line == 0) { 00069 return snprintf(buf, len, "%s: ", file); 00070 } 00071 else { 00072 return snprintf(buf, len, "%s:%d: ", file, line); 00073 } 00074 } 00075 00076 static VALUE 00077 compile_snprintf(rb_encoding *enc, const char *pre, const char *file, int line, const char *fmt, va_list args) 00078 { 00079 VALUE str = rb_enc_str_new(0, 0, enc); 00080 00081 if (file) { 00082 rb_str_cat2(str, file); 00083 if (line) rb_str_catf(str, ":%d", line); 00084 rb_str_cat2(str, ": "); 00085 } 00086 if (pre) rb_str_cat2(str, pre); 00087 rb_str_vcatf(str, fmt, args); 00088 return str; 00089 } 00090 00091 static void 00092 compile_err_append(VALUE mesg) 00093 { 00094 rb_thread_t *th = GET_THREAD(); 00095 VALUE err = th->errinfo; 00096 rb_block_t *prev_base_block = th->base_block; 00097 th->base_block = 0; 00098 /* base_block should be zero while normal Ruby execution */ 00099 /* after this line, any Ruby code *can* run */ 00100 00101 if (th->mild_compile_error) { 00102 if (RTEST(err)) { 00103 VALUE str = rb_obj_as_string(err); 00104 00105 rb_str_cat2(str, "\n"); 00106 rb_str_append(str, mesg); 00107 mesg = str; 00108 } 00109 err = rb_exc_new3(rb_eSyntaxError, mesg); 00110 th->errinfo = err; 00111 } 00112 else { 00113 if (!RTEST(err)) { 00114 err = rb_exc_new2(rb_eSyntaxError, "compile error"); 00115 th->errinfo = err; 00116 } 00117 rb_str_cat2(mesg, "\n"); 00118 rb_write_error_str(mesg); 00119 } 00120 00121 /* returned to the parser world */ 00122 th->base_block = prev_base_block; 00123 } 00124 00125 void 00126 rb_compile_error_with_enc(const char *file, int line, void *enc, const char *fmt, ...) 00127 { 00128 va_list args; 00129 VALUE str; 00130 00131 va_start(args, fmt); 00132 str = compile_snprintf(enc, NULL, file, line, fmt, args); 00133 va_end(args); 00134 compile_err_append(str); 00135 } 00136 00137 void 00138 rb_compile_error(const char *file, int line, const char *fmt, ...) 00139 { 00140 va_list args; 00141 VALUE str; 00142 00143 va_start(args, fmt); 00144 str = compile_snprintf(NULL, NULL, file, line, fmt, args); 00145 va_end(args); 00146 compile_err_append(str); 00147 } 00148 00149 void 00150 rb_compile_error_append(const char *fmt, ...) 00151 { 00152 va_list args; 00153 VALUE str; 00154 00155 va_start(args, fmt); 00156 str = rb_vsprintf(fmt, args); 00157 va_end(args); 00158 compile_err_append(str); 00159 } 00160 00161 static void 00162 compile_warn_print(const char *file, int line, const char *fmt, va_list args) 00163 { 00164 VALUE str; 00165 00166 str = compile_snprintf(NULL, "warning: ", file, line, fmt, args); 00167 rb_str_cat2(str, "\n"); 00168 rb_write_error_str(str); 00169 } 00170 00171 void 00172 rb_compile_warn(const char *file, int line, const char *fmt, ...) 00173 { 00174 va_list args; 00175 00176 if (NIL_P(ruby_verbose)) return; 00177 00178 va_start(args, fmt); 00179 compile_warn_print(file, line, fmt, args); 00180 va_end(args); 00181 } 00182 00183 /* rb_compile_warning() reports only in verbose mode */ 00184 void 00185 rb_compile_warning(const char *file, int line, const char *fmt, ...) 00186 { 00187 va_list args; 00188 00189 if (!RTEST(ruby_verbose)) return; 00190 00191 va_start(args, fmt); 00192 compile_warn_print(file, line, fmt, args); 00193 va_end(args); 00194 } 00195 00196 static void 00197 warn_print(const char *fmt, va_list args) 00198 { 00199 VALUE str = rb_str_new(0, 0); 00200 VALUE file = rb_sourcefilename(); 00201 00202 if (!NIL_P(file)) { 00203 int line = rb_sourceline(); 00204 str = rb_str_append(str, file); 00205 if (line) rb_str_catf(str, ":%d", line); 00206 rb_str_cat2(str, ": "); 00207 } 00208 00209 rb_str_cat2(str, "warning: "); 00210 rb_str_vcatf(str, fmt, args); 00211 rb_str_cat2(str, "\n"); 00212 rb_write_error_str(str); 00213 } 00214 00215 void 00216 rb_warn(const char *fmt, ...) 00217 { 00218 va_list args; 00219 00220 if (NIL_P(ruby_verbose)) return; 00221 00222 va_start(args, fmt); 00223 warn_print(fmt, args); 00224 va_end(args); 00225 } 00226 00227 /* rb_warning() reports only in verbose mode */ 00228 void 00229 rb_warning(const char *fmt, ...) 00230 { 00231 va_list args; 00232 00233 if (!RTEST(ruby_verbose)) return; 00234 00235 va_start(args, fmt); 00236 warn_print(fmt, args); 00237 va_end(args); 00238 } 00239 00240 /* 00241 * call-seq: 00242 * warn(msg, ...) -> nil 00243 * 00244 * Displays each of the given messages followed by a record separator on 00245 * STDERR unless warnings have been disabled (for example with the 00246 * <code>-W0</code> flag). 00247 * 00248 * warn("warning 1", "warning 2") 00249 * 00250 * <em>produces:</em> 00251 * 00252 * warning 1 00253 * warning 2 00254 */ 00255 00256 static VALUE 00257 rb_warn_m(int argc, VALUE *argv, VALUE exc) 00258 { 00259 if (!NIL_P(ruby_verbose) && argc > 0) { 00260 rb_io_puts(argc, argv, rb_stderr); 00261 } 00262 return Qnil; 00263 } 00264 00265 static void 00266 report_bug(const char *file, int line, const char *fmt, va_list args) 00267 { 00268 /* SIGSEGV handler might have a very small stack. Thus we need to use it carefully. */ 00269 char buf[256]; 00270 FILE *out = stderr; 00271 int len = err_position_0(buf, 256, file, line); 00272 00273 if ((ssize_t)fwrite(buf, 1, len, out) == (ssize_t)len || 00274 (ssize_t)fwrite(buf, 1, len, (out = stdout)) == (ssize_t)len) { 00275 00276 fputs("[BUG] ", out); 00277 vsnprintf(buf, 256, fmt, args); 00278 fputs(buf, out); 00279 snprintf(buf, 256, "\n%s\n\n", ruby_description); 00280 fputs(buf, out); 00281 00282 00283 rb_vm_bugreport(); 00284 00285 fprintf(out, REPORTBUG_MSG); 00286 } 00287 } 00288 00289 void 00290 rb_bug(const char *fmt, ...) 00291 { 00292 va_list args; 00293 const char *file = NULL; 00294 int line = 0; 00295 00296 if (GET_THREAD()) { 00297 file = rb_sourcefile(); 00298 line = rb_sourceline(); 00299 } 00300 00301 va_start(args, fmt); 00302 report_bug(file, line, fmt, args); 00303 va_end(args); 00304 00305 #if defined(_WIN32) && defined(RUBY_MSVCRT_VERSION) && RUBY_MSVCRT_VERSION >= 80 00306 _set_abort_behavior( 0, _CALL_REPORTFAULT); 00307 #endif 00308 00309 abort(); 00310 } 00311 00312 void 00313 rb_bug_errno(const char *mesg, int errno_arg) 00314 { 00315 if (errno_arg == 0) 00316 rb_bug("%s: errno == 0 (NOERROR)", mesg); 00317 else { 00318 const char *errno_str = rb_strerrno(errno_arg); 00319 if (errno_str) 00320 rb_bug("%s: %s (%s)", mesg, strerror(errno_arg), errno_str); 00321 else 00322 rb_bug("%s: %s (%d)", mesg, strerror(errno_arg), errno_arg); 00323 } 00324 } 00325 00326 /* 00327 * this is safe to call inside signal handler and timer thread 00328 * (which isn't a Ruby Thread object) 00329 */ 00330 #define write_or_abort(fd, str, len) (write((fd), (str), (len)) < 0 ? abort() : (void)0) 00331 #define WRITE_CONST(fd,str) write_or_abort((fd),(str),sizeof(str) - 1) 00332 00333 void 00334 rb_async_bug_errno(const char *mesg, int errno_arg) 00335 { 00336 WRITE_CONST(2, "[ASYNC BUG] "); 00337 write_or_abort(2, mesg, strlen(mesg)); 00338 WRITE_CONST(2, "\n"); 00339 00340 if (errno_arg == 0) { 00341 WRITE_CONST(2, "errno == 0 (NOERROR)\n"); 00342 } 00343 else { 00344 const char *errno_str = rb_strerrno(errno_arg); 00345 00346 if (!errno_str) 00347 errno_str = "undefined errno"; 00348 write_or_abort(2, errno_str, strlen(errno_str)); 00349 } 00350 WRITE_CONST(2, "\n\n"); 00351 write_or_abort(2, ruby_description, strlen(ruby_description)); 00352 WRITE_CONST(2, "\n\n"); 00353 WRITE_CONST(2, REPORTBUG_MSG); 00354 abort(); 00355 } 00356 00357 void 00358 rb_compile_bug(const char *file, int line, const char *fmt, ...) 00359 { 00360 va_list args; 00361 00362 va_start(args, fmt); 00363 report_bug(file, line, fmt, args); 00364 va_end(args); 00365 00366 abort(); 00367 } 00368 00369 static const char builtin_types[][10] = { 00370 "", /* 0x00, */ 00371 "Object", 00372 "Class", 00373 "Module", 00374 "Float", 00375 "String", 00376 "Regexp", 00377 "Array", 00378 "Hash", 00379 "Struct", 00380 "Bignum", 00381 "File", 00382 "Data", /* internal use: wrapped C pointers */ 00383 "MatchData", /* data of $~ */ 00384 "Complex", 00385 "Rational", 00386 "", /* 0x10 */ 00387 "nil", 00388 "true", 00389 "false", 00390 "Symbol", /* :symbol */ 00391 "Fixnum", 00392 "", /* 0x16 */ 00393 "", /* 0x17 */ 00394 "", /* 0x18 */ 00395 "", /* 0x19 */ 00396 "", /* 0x1a */ 00397 "undef", /* internal use: #undef; should not happen */ 00398 "Node", /* internal use: syntax tree node */ 00399 "iClass", /* internal use: mixed-in module holder */ 00400 }; 00401 00402 const char * 00403 rb_builtin_type_name(int t) 00404 { 00405 const char *name; 00406 if ((unsigned int)t >= numberof(builtin_types)) return 0; 00407 name = builtin_types[t]; 00408 if (*name) return name; 00409 return 0; 00410 } 00411 00412 #define builtin_class_name rb_builtin_class_name 00413 const char * 00414 rb_builtin_class_name(VALUE x) 00415 { 00416 const char *etype; 00417 00418 if (NIL_P(x)) { 00419 etype = "nil"; 00420 } 00421 else if (FIXNUM_P(x)) { 00422 etype = "Fixnum"; 00423 } 00424 else if (SYMBOL_P(x)) { 00425 etype = "Symbol"; 00426 } 00427 else if (RB_TYPE_P(x, T_TRUE)) { 00428 etype = "true"; 00429 } 00430 else if (RB_TYPE_P(x, T_FALSE)) { 00431 etype = "false"; 00432 } 00433 else { 00434 etype = rb_obj_classname(x); 00435 } 00436 return etype; 00437 } 00438 00439 void 00440 rb_check_type(VALUE x, int t) 00441 { 00442 int xt; 00443 00444 if (x == Qundef) { 00445 rb_bug("undef leaked to the Ruby space"); 00446 } 00447 00448 xt = TYPE(x); 00449 if (xt != t || (xt == T_DATA && RTYPEDDATA_P(x))) { 00450 const char *tname = rb_builtin_type_name(t); 00451 if (tname) { 00452 rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", 00453 builtin_class_name(x), tname); 00454 } 00455 if (xt > T_MASK && xt <= 0x3f) { 00456 rb_fatal("unknown type 0x%x (0x%x given, probably comes from extension library for ruby 1.8)", t, xt); 00457 } 00458 rb_bug("unknown type 0x%x (0x%x given)", t, xt); 00459 } 00460 } 00461 00462 int 00463 rb_typeddata_inherited_p(const rb_data_type_t *child, const rb_data_type_t *parent) 00464 { 00465 while (child) { 00466 if (child == parent) return 1; 00467 child = child->parent; 00468 } 00469 return 0; 00470 } 00471 00472 int 00473 rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type) 00474 { 00475 if (!RB_TYPE_P(obj, T_DATA) || 00476 !RTYPEDDATA_P(obj) || !rb_typeddata_inherited_p(RTYPEDDATA_TYPE(obj), data_type)) { 00477 return 0; 00478 } 00479 return 1; 00480 } 00481 00482 void * 00483 rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type) 00484 { 00485 const char *etype; 00486 static const char mesg[] = "wrong argument type %s (expected %s)"; 00487 00488 if (!RB_TYPE_P(obj, T_DATA)) { 00489 etype = builtin_class_name(obj); 00490 rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name); 00491 } 00492 if (!RTYPEDDATA_P(obj)) { 00493 etype = rb_obj_classname(obj); 00494 rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name); 00495 } 00496 else if (!rb_typeddata_inherited_p(RTYPEDDATA_TYPE(obj), data_type)) { 00497 etype = RTYPEDDATA_TYPE(obj)->wrap_struct_name; 00498 rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name); 00499 } 00500 return DATA_PTR(obj); 00501 } 00502 00503 /* exception classes */ 00504 VALUE rb_eException; 00505 VALUE rb_eSystemExit; 00506 VALUE rb_eInterrupt; 00507 VALUE rb_eSignal; 00508 VALUE rb_eFatal; 00509 VALUE rb_eStandardError; 00510 VALUE rb_eRuntimeError; 00511 VALUE rb_eTypeError; 00512 VALUE rb_eArgError; 00513 VALUE rb_eIndexError; 00514 VALUE rb_eKeyError; 00515 VALUE rb_eRangeError; 00516 VALUE rb_eNameError; 00517 VALUE rb_eEncodingError; 00518 VALUE rb_eEncCompatError; 00519 VALUE rb_eNoMethodError; 00520 VALUE rb_eSecurityError; 00521 VALUE rb_eNotImpError; 00522 VALUE rb_eNoMemError; 00523 VALUE rb_cNameErrorMesg; 00524 00525 VALUE rb_eScriptError; 00526 VALUE rb_eSyntaxError; 00527 VALUE rb_eLoadError; 00528 00529 VALUE rb_eSystemCallError; 00530 VALUE rb_mErrno; 00531 static VALUE rb_eNOERROR; 00532 00533 #undef rb_exc_new2 00534 00535 VALUE 00536 rb_exc_new(VALUE etype, const char *ptr, long len) 00537 { 00538 return rb_funcall(etype, rb_intern("new"), 1, rb_str_new(ptr, len)); 00539 } 00540 00541 VALUE 00542 rb_exc_new2(VALUE etype, const char *s) 00543 { 00544 return rb_exc_new(etype, s, strlen(s)); 00545 } 00546 00547 VALUE 00548 rb_exc_new3(VALUE etype, VALUE str) 00549 { 00550 StringValue(str); 00551 return rb_funcall(etype, rb_intern("new"), 1, str); 00552 } 00553 00554 /* 00555 * call-seq: 00556 * Exception.new(msg = nil) -> exception 00557 * 00558 * Construct a new Exception object, optionally passing in 00559 * a message. 00560 */ 00561 00562 static VALUE 00563 exc_initialize(int argc, VALUE *argv, VALUE exc) 00564 { 00565 VALUE arg; 00566 00567 rb_scan_args(argc, argv, "01", &arg); 00568 rb_iv_set(exc, "mesg", arg); 00569 rb_iv_set(exc, "bt", Qnil); 00570 00571 return exc; 00572 } 00573 00574 /* 00575 * Document-method: exception 00576 * 00577 * call-seq: 00578 * exc.exception(string) -> an_exception or exc 00579 * 00580 * With no argument, or if the argument is the same as the receiver, 00581 * return the receiver. Otherwise, create a new 00582 * exception object of the same class as the receiver, but with a 00583 * message equal to <code>string.to_str</code>. 00584 * 00585 */ 00586 00587 static VALUE 00588 exc_exception(int argc, VALUE *argv, VALUE self) 00589 { 00590 VALUE exc; 00591 00592 if (argc == 0) return self; 00593 if (argc == 1 && self == argv[0]) return self; 00594 exc = rb_obj_clone(self); 00595 exc_initialize(argc, argv, exc); 00596 00597 return exc; 00598 } 00599 00600 /* 00601 * call-seq: 00602 * exception.to_s -> string 00603 * 00604 * Returns exception's message (or the name of the exception if 00605 * no message is set). 00606 */ 00607 00608 static VALUE 00609 exc_to_s(VALUE exc) 00610 { 00611 VALUE mesg = rb_attr_get(exc, rb_intern("mesg")); 00612 VALUE r = Qnil; 00613 00614 if (NIL_P(mesg)) return rb_class_name(CLASS_OF(exc)); 00615 r = rb_String(mesg); 00616 return r; 00617 } 00618 00619 /* 00620 * call-seq: 00621 * exception.message -> string 00622 * 00623 * Returns the result of invoking <code>exception.to_s</code>. 00624 * Normally this returns the exception's message or name. By 00625 * supplying a to_str method, exceptions are agreeing to 00626 * be used where Strings are expected. 00627 */ 00628 00629 static VALUE 00630 exc_message(VALUE exc) 00631 { 00632 return rb_funcall(exc, rb_intern("to_s"), 0, 0); 00633 } 00634 00635 /* 00636 * call-seq: 00637 * exception.inspect -> string 00638 * 00639 * Return this exception's class name and message 00640 */ 00641 00642 static VALUE 00643 exc_inspect(VALUE exc) 00644 { 00645 VALUE str, klass; 00646 00647 klass = CLASS_OF(exc); 00648 exc = rb_obj_as_string(exc); 00649 if (RSTRING_LEN(exc) == 0) { 00650 return rb_str_dup(rb_class_name(klass)); 00651 } 00652 00653 str = rb_str_buf_new2("#<"); 00654 klass = rb_class_name(klass); 00655 rb_str_buf_append(str, klass); 00656 rb_str_buf_cat(str, ": ", 2); 00657 rb_str_buf_append(str, exc); 00658 rb_str_buf_cat(str, ">", 1); 00659 00660 return str; 00661 } 00662 00663 /* 00664 * call-seq: 00665 * exception.backtrace -> array 00666 * 00667 * Returns any backtrace associated with the exception. The backtrace 00668 * is an array of strings, each containing either ``filename:lineNo: in 00669 * `method''' or ``filename:lineNo.'' 00670 * 00671 * def a 00672 * raise "boom" 00673 * end 00674 * 00675 * def b 00676 * a() 00677 * end 00678 * 00679 * begin 00680 * b() 00681 * rescue => detail 00682 * print detail.backtrace.join("\n") 00683 * end 00684 * 00685 * <em>produces:</em> 00686 * 00687 * prog.rb:2:in `a' 00688 * prog.rb:6:in `b' 00689 * prog.rb:10 00690 */ 00691 00692 static VALUE 00693 exc_backtrace(VALUE exc) 00694 { 00695 ID bt; 00696 VALUE obj; 00697 00698 CONST_ID(bt, "bt"); 00699 obj = rb_attr_get(exc, bt); 00700 00701 if (rb_backtrace_p(obj)) { 00702 obj = rb_backtrace_to_str_ary(obj); 00703 /* rb_iv_set(exc, "bt", obj); */ 00704 } 00705 00706 return obj; 00707 } 00708 00709 VALUE 00710 rb_check_backtrace(VALUE bt) 00711 { 00712 long i; 00713 static const char err[] = "backtrace must be Array of String"; 00714 00715 if (!NIL_P(bt)) { 00716 if (RB_TYPE_P(bt, T_STRING)) return rb_ary_new3(1, bt); 00717 if (rb_backtrace_p(bt)) return bt; 00718 if (!RB_TYPE_P(bt, T_ARRAY)) { 00719 rb_raise(rb_eTypeError, err); 00720 } 00721 for (i=0;i<RARRAY_LEN(bt);i++) { 00722 if (!RB_TYPE_P(RARRAY_PTR(bt)[i], T_STRING)) { 00723 rb_raise(rb_eTypeError, err); 00724 } 00725 } 00726 } 00727 return bt; 00728 } 00729 00730 /* 00731 * call-seq: 00732 * exc.set_backtrace(backtrace) -> array 00733 * 00734 * Sets the backtrace information associated with +exc+. The +backtrace+ must 00735 * be an array of String objects or a single String in the format described 00736 * in Exception#backtrace. 00737 * 00738 */ 00739 00740 static VALUE 00741 exc_set_backtrace(VALUE exc, VALUE bt) 00742 { 00743 return rb_iv_set(exc, "bt", rb_check_backtrace(bt)); 00744 } 00745 00746 VALUE 00747 rb_exc_set_backtrace(VALUE exc, VALUE bt) 00748 { 00749 return exc_set_backtrace(exc, bt); 00750 } 00751 00752 static VALUE 00753 try_convert_to_exception(VALUE obj) 00754 { 00755 ID id_exception; 00756 CONST_ID(id_exception, "exception"); 00757 return rb_check_funcall(obj, id_exception, 0, 0); 00758 } 00759 00760 /* 00761 * call-seq: 00762 * exc == obj -> true or false 00763 * 00764 * Equality---If <i>obj</i> is not an <code>Exception</code>, returns 00765 * <code>false</code>. Otherwise, returns <code>true</code> if <i>exc</i> and 00766 * <i>obj</i> share same class, messages, and backtrace. 00767 */ 00768 00769 static VALUE 00770 exc_equal(VALUE exc, VALUE obj) 00771 { 00772 VALUE mesg, backtrace; 00773 ID id_mesg; 00774 00775 if (exc == obj) return Qtrue; 00776 CONST_ID(id_mesg, "mesg"); 00777 00778 if (rb_obj_class(exc) != rb_obj_class(obj)) { 00779 int status = 0; 00780 ID id_message, id_backtrace; 00781 CONST_ID(id_message, "message"); 00782 CONST_ID(id_backtrace, "backtrace"); 00783 00784 obj = rb_protect(try_convert_to_exception, obj, &status); 00785 if (status || obj == Qundef) { 00786 rb_set_errinfo(Qnil); 00787 return Qfalse; 00788 } 00789 if (rb_obj_class(exc) != rb_obj_class(obj)) return Qfalse; 00790 mesg = rb_check_funcall(obj, id_message, 0, 0); 00791 if (mesg == Qundef) return Qfalse; 00792 backtrace = rb_check_funcall(obj, id_backtrace, 0, 0); 00793 if (backtrace == Qundef) return Qfalse; 00794 } 00795 else { 00796 mesg = rb_attr_get(obj, id_mesg); 00797 backtrace = exc_backtrace(obj); 00798 } 00799 00800 if (!rb_equal(rb_attr_get(exc, id_mesg), mesg)) 00801 return Qfalse; 00802 if (!rb_equal(exc_backtrace(exc), backtrace)) 00803 return Qfalse; 00804 return Qtrue; 00805 } 00806 00807 /* 00808 * call-seq: 00809 * SystemExit.new -> system_exit 00810 * SystemExit.new(status) -> system_exit 00811 * SystemExit.new(status, msg) -> system_exit 00812 * SystemExit.new(msg) -> system_exit 00813 * 00814 * Create a new +SystemExit+ exception with the given status and message. 00815 * Status is true, false, or an integer. 00816 * If status is not given, true is used. 00817 */ 00818 00819 static VALUE 00820 exit_initialize(int argc, VALUE *argv, VALUE exc) 00821 { 00822 VALUE status; 00823 if (argc > 0) { 00824 status = *argv; 00825 00826 switch (status) { 00827 case Qtrue: 00828 status = INT2FIX(EXIT_SUCCESS); 00829 ++argv; 00830 --argc; 00831 break; 00832 case Qfalse: 00833 status = INT2FIX(EXIT_FAILURE); 00834 ++argv; 00835 --argc; 00836 break; 00837 default: 00838 status = rb_check_to_int(status); 00839 if (NIL_P(status)) { 00840 status = INT2FIX(EXIT_SUCCESS); 00841 } 00842 else { 00843 #if EXIT_SUCCESS != 0 00844 if (status == INT2FIX(0)) 00845 status = INT2FIX(EXIT_SUCCESS); 00846 #endif 00847 ++argv; 00848 --argc; 00849 } 00850 break; 00851 } 00852 } 00853 else { 00854 status = INT2FIX(EXIT_SUCCESS); 00855 } 00856 rb_call_super(argc, argv); 00857 rb_iv_set(exc, "status", status); 00858 return exc; 00859 } 00860 00861 00862 /* 00863 * call-seq: 00864 * system_exit.status -> fixnum 00865 * 00866 * Return the status value associated with this system exit. 00867 */ 00868 00869 static VALUE 00870 exit_status(VALUE exc) 00871 { 00872 return rb_attr_get(exc, rb_intern("status")); 00873 } 00874 00875 00876 /* 00877 * call-seq: 00878 * system_exit.success? -> true or false 00879 * 00880 * Returns +true+ if exiting successful, +false+ if not. 00881 */ 00882 00883 static VALUE 00884 exit_success_p(VALUE exc) 00885 { 00886 VALUE status_val = rb_attr_get(exc, rb_intern("status")); 00887 int status; 00888 00889 if (NIL_P(status_val)) 00890 return Qtrue; 00891 status = NUM2INT(status_val); 00892 if (WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS) 00893 return Qtrue; 00894 00895 return Qfalse; 00896 } 00897 00898 void 00899 rb_name_error(ID id, const char *fmt, ...) 00900 { 00901 VALUE exc, argv[2]; 00902 va_list args; 00903 00904 va_start(args, fmt); 00905 argv[0] = rb_vsprintf(fmt, args); 00906 va_end(args); 00907 00908 argv[1] = ID2SYM(id); 00909 exc = rb_class_new_instance(2, argv, rb_eNameError); 00910 rb_exc_raise(exc); 00911 } 00912 00913 void 00914 rb_name_error_str(VALUE str, const char *fmt, ...) 00915 { 00916 VALUE exc, argv[2]; 00917 va_list args; 00918 00919 va_start(args, fmt); 00920 argv[0] = rb_vsprintf(fmt, args); 00921 va_end(args); 00922 00923 argv[1] = str; 00924 exc = rb_class_new_instance(2, argv, rb_eNameError); 00925 rb_exc_raise(exc); 00926 } 00927 00928 /* 00929 * call-seq: 00930 * NameError.new(msg [, name]) -> name_error 00931 * 00932 * Construct a new NameError exception. If given the <i>name</i> 00933 * parameter may subsequently be examined using the <code>NameError.name</code> 00934 * method. 00935 */ 00936 00937 static VALUE 00938 name_err_initialize(int argc, VALUE *argv, VALUE self) 00939 { 00940 VALUE name; 00941 00942 name = (argc > 1) ? argv[--argc] : Qnil; 00943 rb_call_super(argc, argv); 00944 rb_iv_set(self, "name", name); 00945 return self; 00946 } 00947 00948 /* 00949 * call-seq: 00950 * name_error.name -> string or nil 00951 * 00952 * Return the name associated with this NameError exception. 00953 */ 00954 00955 static VALUE 00956 name_err_name(VALUE self) 00957 { 00958 return rb_attr_get(self, rb_intern("name")); 00959 } 00960 00961 /* 00962 * call-seq: 00963 * name_error.to_s -> string 00964 * 00965 * Produce a nicely-formatted string representing the +NameError+. 00966 */ 00967 00968 static VALUE 00969 name_err_to_s(VALUE exc) 00970 { 00971 VALUE mesg = rb_attr_get(exc, rb_intern("mesg")); 00972 VALUE str = mesg; 00973 00974 if (NIL_P(mesg)) return rb_class_name(CLASS_OF(exc)); 00975 StringValue(str); 00976 return str; 00977 } 00978 00979 /* 00980 * call-seq: 00981 * NoMethodError.new(msg, name [, args]) -> no_method_error 00982 * 00983 * Construct a NoMethodError exception for a method of the given name 00984 * called with the given arguments. The name may be accessed using 00985 * the <code>#name</code> method on the resulting object, and the 00986 * arguments using the <code>#args</code> method. 00987 */ 00988 00989 static VALUE 00990 nometh_err_initialize(int argc, VALUE *argv, VALUE self) 00991 { 00992 VALUE args = (argc > 2) ? argv[--argc] : Qnil; 00993 name_err_initialize(argc, argv, self); 00994 rb_iv_set(self, "args", args); 00995 return self; 00996 } 00997 00998 /* :nodoc: */ 00999 #define NAME_ERR_MESG_COUNT 3 01000 01001 static void 01002 name_err_mesg_mark(void *p) 01003 { 01004 VALUE *ptr = p; 01005 rb_gc_mark_locations(ptr, ptr+NAME_ERR_MESG_COUNT); 01006 } 01007 01008 #define name_err_mesg_free RUBY_TYPED_DEFAULT_FREE 01009 01010 static size_t 01011 name_err_mesg_memsize(const void *p) 01012 { 01013 return p ? (NAME_ERR_MESG_COUNT * sizeof(VALUE)) : 0; 01014 } 01015 01016 static const rb_data_type_t name_err_mesg_data_type = { 01017 "name_err_mesg", 01018 { 01019 name_err_mesg_mark, 01020 name_err_mesg_free, 01021 name_err_mesg_memsize, 01022 }, 01023 }; 01024 01025 /* :nodoc: */ 01026 VALUE 01027 rb_name_err_mesg_new(VALUE obj, VALUE mesg, VALUE recv, VALUE method) 01028 { 01029 VALUE *ptr = ALLOC_N(VALUE, NAME_ERR_MESG_COUNT); 01030 VALUE result; 01031 01032 ptr[0] = mesg; 01033 ptr[1] = recv; 01034 ptr[2] = method; 01035 result = TypedData_Wrap_Struct(rb_cNameErrorMesg, &name_err_mesg_data_type, ptr); 01036 RB_GC_GUARD(mesg); 01037 RB_GC_GUARD(recv); 01038 RB_GC_GUARD(method); 01039 return result; 01040 } 01041 01042 /* :nodoc: */ 01043 static VALUE 01044 name_err_mesg_equal(VALUE obj1, VALUE obj2) 01045 { 01046 VALUE *ptr1, *ptr2; 01047 int i; 01048 01049 if (obj1 == obj2) return Qtrue; 01050 if (rb_obj_class(obj2) != rb_cNameErrorMesg) 01051 return Qfalse; 01052 01053 TypedData_Get_Struct(obj1, VALUE, &name_err_mesg_data_type, ptr1); 01054 TypedData_Get_Struct(obj2, VALUE, &name_err_mesg_data_type, ptr2); 01055 for (i=0; i<NAME_ERR_MESG_COUNT; i++) { 01056 if (!rb_equal(ptr1[i], ptr2[i])) 01057 return Qfalse; 01058 } 01059 return Qtrue; 01060 } 01061 01062 /* :nodoc: */ 01063 static VALUE 01064 name_err_mesg_to_str(VALUE obj) 01065 { 01066 VALUE *ptr, mesg; 01067 TypedData_Get_Struct(obj, VALUE, &name_err_mesg_data_type, ptr); 01068 01069 mesg = ptr[0]; 01070 if (NIL_P(mesg)) return Qnil; 01071 else { 01072 const char *desc = 0; 01073 VALUE d = 0, args[NAME_ERR_MESG_COUNT]; 01074 int state = 0; 01075 01076 obj = ptr[1]; 01077 switch (obj) { 01078 case Qnil: 01079 desc = "nil"; 01080 break; 01081 case Qtrue: 01082 desc = "true"; 01083 break; 01084 case Qfalse: 01085 desc = "false"; 01086 break; 01087 default: 01088 d = rb_protect(rb_inspect, obj, &state); 01089 if (state) 01090 rb_set_errinfo(Qnil); 01091 if (NIL_P(d) || RSTRING_LEN(d) > 65) { 01092 d = rb_any_to_s(obj); 01093 } 01094 desc = RSTRING_PTR(d); 01095 break; 01096 } 01097 if (desc && desc[0] != '#') { 01098 d = d ? rb_str_dup(d) : rb_str_new2(desc); 01099 rb_str_cat2(d, ":"); 01100 rb_str_append(d, rb_class_name(CLASS_OF(obj))); 01101 } 01102 args[0] = mesg; 01103 args[1] = ptr[2]; 01104 args[2] = d; 01105 mesg = rb_f_sprintf(NAME_ERR_MESG_COUNT, args); 01106 } 01107 return mesg; 01108 } 01109 01110 /* :nodoc: */ 01111 static VALUE 01112 name_err_mesg_dump(VALUE obj, VALUE limit) 01113 { 01114 return name_err_mesg_to_str(obj); 01115 } 01116 01117 /* :nodoc: */ 01118 static VALUE 01119 name_err_mesg_load(VALUE klass, VALUE str) 01120 { 01121 return str; 01122 } 01123 01124 /* 01125 * call-seq: 01126 * no_method_error.args -> obj 01127 * 01128 * Return the arguments passed in as the third parameter to 01129 * the constructor. 01130 */ 01131 01132 static VALUE 01133 nometh_err_args(VALUE self) 01134 { 01135 return rb_attr_get(self, rb_intern("args")); 01136 } 01137 01138 void 01139 rb_invalid_str(const char *str, const char *type) 01140 { 01141 VALUE s = rb_str_new2(str); 01142 01143 rb_raise(rb_eArgError, "invalid value for %s: %+"PRIsVALUE, type, s); 01144 } 01145 01146 /* 01147 * Document-module: Errno 01148 * 01149 * Ruby exception objects are subclasses of <code>Exception</code>. 01150 * However, operating systems typically report errors using plain 01151 * integers. Module <code>Errno</code> is created dynamically to map 01152 * these operating system errors to Ruby classes, with each error 01153 * number generating its own subclass of <code>SystemCallError</code>. 01154 * As the subclass is created in module <code>Errno</code>, its name 01155 * will start <code>Errno::</code>. 01156 * 01157 * The names of the <code>Errno::</code> classes depend on 01158 * the environment in which Ruby runs. On a typical Unix or Windows 01159 * platform, there are <code>Errno</code> classes such as 01160 * <code>Errno::EACCES</code>, <code>Errno::EAGAIN</code>, 01161 * <code>Errno::EINTR</code>, and so on. 01162 * 01163 * The integer operating system error number corresponding to a 01164 * particular error is available as the class constant 01165 * <code>Errno::</code><em>error</em><code>::Errno</code>. 01166 * 01167 * Errno::EACCES::Errno #=> 13 01168 * Errno::EAGAIN::Errno #=> 11 01169 * Errno::EINTR::Errno #=> 4 01170 * 01171 * The full list of operating system errors on your particular platform 01172 * are available as the constants of <code>Errno</code>. 01173 * 01174 * Errno.constants #=> :E2BIG, :EACCES, :EADDRINUSE, :EADDRNOTAVAIL, ... 01175 */ 01176 01177 static st_table *syserr_tbl; 01178 01179 static VALUE 01180 set_syserr(int n, const char *name) 01181 { 01182 st_data_t error; 01183 01184 if (!st_lookup(syserr_tbl, n, &error)) { 01185 error = rb_define_class_under(rb_mErrno, name, rb_eSystemCallError); 01186 rb_define_const(error, "Errno", INT2NUM(n)); 01187 st_add_direct(syserr_tbl, n, error); 01188 } 01189 else { 01190 rb_define_const(rb_mErrno, name, error); 01191 } 01192 return error; 01193 } 01194 01195 static VALUE 01196 get_syserr(int n) 01197 { 01198 st_data_t error; 01199 01200 if (!st_lookup(syserr_tbl, n, &error)) { 01201 char name[8]; /* some Windows' errno have 5 digits. */ 01202 01203 snprintf(name, sizeof(name), "E%03d", n); 01204 error = set_syserr(n, name); 01205 } 01206 return error; 01207 } 01208 01209 /* 01210 * call-seq: 01211 * SystemCallError.new(msg, errno) -> system_call_error_subclass 01212 * 01213 * If _errno_ corresponds to a known system error code, constructs 01214 * the appropriate <code>Errno</code> class for that error, otherwise 01215 * constructs a generic <code>SystemCallError</code> object. The 01216 * error number is subsequently available via the <code>errno</code> 01217 * method. 01218 */ 01219 01220 static VALUE 01221 syserr_initialize(int argc, VALUE *argv, VALUE self) 01222 { 01223 #if !defined(_WIN32) 01224 char *strerror(); 01225 #endif 01226 const char *err; 01227 VALUE mesg, error; 01228 VALUE klass = rb_obj_class(self); 01229 01230 if (klass == rb_eSystemCallError) { 01231 st_data_t data = (st_data_t)klass; 01232 rb_scan_args(argc, argv, "11", &mesg, &error); 01233 if (argc == 1 && FIXNUM_P(mesg)) { 01234 error = mesg; mesg = Qnil; 01235 } 01236 if (!NIL_P(error) && st_lookup(syserr_tbl, NUM2LONG(error), &data)) { 01237 klass = (VALUE)data; 01238 /* change class */ 01239 if (!RB_TYPE_P(self, T_OBJECT)) { /* insurance to avoid type crash */ 01240 rb_raise(rb_eTypeError, "invalid instance type"); 01241 } 01242 RBASIC(self)->klass = klass; 01243 } 01244 } 01245 else { 01246 rb_scan_args(argc, argv, "01", &mesg); 01247 error = rb_const_get(klass, rb_intern("Errno")); 01248 } 01249 if (!NIL_P(error)) err = strerror(NUM2INT(error)); 01250 else err = "unknown error"; 01251 if (!NIL_P(mesg)) { 01252 rb_encoding *le = rb_locale_encoding(); 01253 VALUE str = StringValue(mesg); 01254 rb_encoding *me = rb_enc_get(mesg); 01255 01256 mesg = rb_sprintf("%s - %"PRIsVALUE, err, mesg); 01257 if (le != me && rb_enc_asciicompat(me)) { 01258 le = me; 01259 }/* else assume err is non ASCII string. */ 01260 OBJ_INFECT(mesg, str); 01261 rb_enc_associate(mesg, le); 01262 } 01263 else { 01264 mesg = rb_str_new2(err); 01265 rb_enc_associate(mesg, rb_locale_encoding()); 01266 } 01267 rb_call_super(1, &mesg); 01268 rb_iv_set(self, "errno", error); 01269 return self; 01270 } 01271 01272 /* 01273 * call-seq: 01274 * system_call_error.errno -> fixnum 01275 * 01276 * Return this SystemCallError's error number. 01277 */ 01278 01279 static VALUE 01280 syserr_errno(VALUE self) 01281 { 01282 return rb_attr_get(self, rb_intern("errno")); 01283 } 01284 01285 /* 01286 * call-seq: 01287 * system_call_error === other -> true or false 01288 * 01289 * Return +true+ if the receiver is a generic +SystemCallError+, or 01290 * if the error numbers +self+ and _other_ are the same. 01291 */ 01292 01293 static VALUE 01294 syserr_eqq(VALUE self, VALUE exc) 01295 { 01296 VALUE num, e; 01297 ID en; 01298 01299 CONST_ID(en, "errno"); 01300 01301 if (!rb_obj_is_kind_of(exc, rb_eSystemCallError)) { 01302 if (!rb_respond_to(exc, en)) return Qfalse; 01303 } 01304 else if (self == rb_eSystemCallError) return Qtrue; 01305 01306 num = rb_attr_get(exc, rb_intern("errno")); 01307 if (NIL_P(num)) { 01308 num = rb_funcall(exc, en, 0, 0); 01309 } 01310 e = rb_const_get(self, rb_intern("Errno")); 01311 if (FIXNUM_P(num) ? num == e : rb_equal(num, e)) 01312 return Qtrue; 01313 return Qfalse; 01314 } 01315 01316 01317 /* 01318 * Document-class: StandardError 01319 * 01320 * The most standard error types are subclasses of StandardError. A 01321 * rescue clause without an explicit Exception class will rescue all 01322 * StandardErrors (and only those). 01323 * 01324 * def foo 01325 * raise "Oups" 01326 * end 01327 * foo rescue "Hello" #=> "Hello" 01328 * 01329 * On the other hand: 01330 * 01331 * require 'does/not/exist' rescue "Hi" 01332 * 01333 * <em>raises the exception:</em> 01334 * 01335 * LoadError: no such file to load -- does/not/exist 01336 * 01337 */ 01338 01339 /* 01340 * Document-class: SystemExit 01341 * 01342 * Raised by +exit+ to initiate the termination of the script. 01343 */ 01344 01345 /* 01346 * Document-class: SignalException 01347 * 01348 * Raised when a signal is received. 01349 * 01350 * begin 01351 * Process.kill('HUP',Process.pid) 01352 * sleep # wait for receiver to handle signal sent by Process.kill 01353 * rescue SignalException => e 01354 * puts "received Exception #{e}" 01355 * end 01356 * 01357 * <em>produces:</em> 01358 * 01359 * received Exception SIGHUP 01360 */ 01361 01362 /* 01363 * Document-class: Interrupt 01364 * 01365 * Raised with the interrupt signal is received, typically because the 01366 * user pressed on Control-C (on most posix platforms). As such, it is a 01367 * subclass of +SignalException+. 01368 * 01369 * begin 01370 * puts "Press ctrl-C when you get bored" 01371 * loop {} 01372 * rescue Interrupt => e 01373 * puts "Note: You will typically use Signal.trap instead." 01374 * end 01375 * 01376 * <em>produces:</em> 01377 * 01378 * Press ctrl-C when you get bored 01379 * 01380 * <em>then waits until it is interrupted with Control-C and then prints:</em> 01381 * 01382 * Note: You will typically use Signal.trap instead. 01383 */ 01384 01385 /* 01386 * Document-class: TypeError 01387 * 01388 * Raised when encountering an object that is not of the expected type. 01389 * 01390 * [1, 2, 3].first("two") 01391 * 01392 * <em>raises the exception:</em> 01393 * 01394 * TypeError: no implicit conversion of String into Integer 01395 * 01396 */ 01397 01398 /* 01399 * Document-class: ArgumentError 01400 * 01401 * Raised when the arguments are wrong and there isn't a more specific 01402 * Exception class. 01403 * 01404 * Ex: passing the wrong number of arguments 01405 * 01406 * [1, 2, 3].first(4, 5) 01407 * 01408 * <em>raises the exception:</em> 01409 * 01410 * ArgumentError: wrong number of arguments (2 for 1) 01411 * 01412 * Ex: passing an argument that is not acceptable: 01413 * 01414 * [1, 2, 3].first(-4) 01415 * 01416 * <em>raises the exception:</em> 01417 * 01418 * ArgumentError: negative array size 01419 */ 01420 01421 /* 01422 * Document-class: IndexError 01423 * 01424 * Raised when the given index is invalid. 01425 * 01426 * a = [:foo, :bar] 01427 * a.fetch(0) #=> :foo 01428 * a[4] #=> nil 01429 * a.fetch(4) #=> IndexError: index 4 outside of array bounds: -2...2 01430 * 01431 */ 01432 01433 /* 01434 * Document-class: KeyError 01435 * 01436 * Raised when the specified key is not found. It is a subclass of 01437 * IndexError. 01438 * 01439 * h = {"foo" => :bar} 01440 * h.fetch("foo") #=> :bar 01441 * h.fetch("baz") #=> KeyError: key not found: "baz" 01442 * 01443 */ 01444 01445 /* 01446 * Document-class: RangeError 01447 * 01448 * Raised when a given numerical value is out of range. 01449 * 01450 * [1, 2, 3].drop(1 << 100) 01451 * 01452 * <em>raises the exception:</em> 01453 * 01454 * RangeError: bignum too big to convert into `long' 01455 */ 01456 01457 /* 01458 * Document-class: ScriptError 01459 * 01460 * ScriptError is the superclass for errors raised when a script 01461 * can not be executed because of a +LoadError+, 01462 * +NotImplementedError+ or a +SyntaxError+. Note these type of 01463 * +ScriptErrors+ are not +StandardError+ and will not be 01464 * rescued unless it is specified explicitly (or its ancestor 01465 * +Exception+). 01466 */ 01467 01468 /* 01469 * Document-class: SyntaxError 01470 * 01471 * Raised when encountering Ruby code with an invalid syntax. 01472 * 01473 * eval("1+1=2") 01474 * 01475 * <em>raises the exception:</em> 01476 * 01477 * SyntaxError: (eval):1: syntax error, unexpected '=', expecting $end 01478 */ 01479 01480 /* 01481 * Document-class: LoadError 01482 * 01483 * Raised when a file required (a Ruby script, extension library, ...) 01484 * fails to load. 01485 * 01486 * require 'this/file/does/not/exist' 01487 * 01488 * <em>raises the exception:</em> 01489 * 01490 * LoadError: no such file to load -- this/file/does/not/exist 01491 */ 01492 01493 /* 01494 * Document-class: NotImplementedError 01495 * 01496 * Raised when a feature is not implemented on the current platform. For 01497 * example, methods depending on the +fsync+ or +fork+ system calls may 01498 * raise this exception if the underlying operating system or Ruby 01499 * runtime does not support them. 01500 * 01501 * Note that if +fork+ raises a +NotImplementedError+, then 01502 * <code>respond_to?(:fork)</code> returns +false+. 01503 */ 01504 01505 /* 01506 * Document-class: NameError 01507 * 01508 * Raised when a given name is invalid or undefined. 01509 * 01510 * puts foo 01511 * 01512 * <em>raises the exception:</em> 01513 * 01514 * NameError: undefined local variable or method `foo' for main:Object 01515 * 01516 * Since constant names must start with a capital: 01517 * 01518 * Fixnum.const_set :answer, 42 01519 * 01520 * <em>raises the exception:</em> 01521 * 01522 * NameError: wrong constant name answer 01523 */ 01524 01525 /* 01526 * Document-class: NoMethodError 01527 * 01528 * Raised when a method is called on a receiver which doesn't have it 01529 * defined and also fails to respond with +method_missing+. 01530 * 01531 * "hello".to_ary 01532 * 01533 * <em>raises the exception:</em> 01534 * 01535 * NoMethodError: undefined method `to_ary' for "hello":String 01536 */ 01537 01538 /* 01539 * Document-class: RuntimeError 01540 * 01541 * A generic error class raised when an invalid operation is attempted. 01542 * 01543 * [1, 2, 3].freeze << 4 01544 * 01545 * <em>raises the exception:</em> 01546 * 01547 * RuntimeError: can't modify frozen array 01548 * 01549 * Kernel.raise will raise a RuntimeError if no Exception class is 01550 * specified. 01551 * 01552 * raise "ouch" 01553 * 01554 * <em>raises the exception:</em> 01555 * 01556 * RuntimeError: ouch 01557 */ 01558 01559 /* 01560 * Document-class: SecurityError 01561 * 01562 * Raised when attempting a potential unsafe operation, typically when 01563 * the $SAFE level is raised above 0. 01564 * 01565 * foo = "bar" 01566 * proc = Proc.new do 01567 * $SAFE = 4 01568 * foo.gsub! "a", "*" 01569 * end 01570 * proc.call 01571 * 01572 * <em>raises the exception:</em> 01573 * 01574 * SecurityError: Insecure: can't modify string 01575 */ 01576 01577 /* 01578 * Document-class: NoMemoryError 01579 * 01580 * Raised when memory allocation fails. 01581 */ 01582 01583 /* 01584 * Document-class: SystemCallError 01585 * 01586 * SystemCallError is the base class for all low-level 01587 * platform-dependent errors. 01588 * 01589 * The errors available on the current platform are subclasses of 01590 * SystemCallError and are defined in the Errno module. 01591 * 01592 * File.open("does/not/exist") 01593 * 01594 * <em>raises the exception:</em> 01595 * 01596 * Errno::ENOENT: No such file or directory - does/not/exist 01597 */ 01598 01599 /* 01600 * Document-class: EncodingError 01601 * 01602 * EncodingError is the base class for encoding errors. 01603 */ 01604 01605 /* 01606 * Document-class: Encoding::CompatibilityError 01607 * 01608 * Raised by Encoding and String methods when the source encoding is 01609 * incompatible with the target encoding. 01610 */ 01611 01612 /* 01613 * Document-class: fatal 01614 * 01615 * fatal is an Exception that is raised when ruby has encountered a fatal 01616 * error and must exit. You are not able to rescue fatal. 01617 */ 01618 01619 /* 01620 * Document-class: NameError::message 01621 * :nodoc: 01622 */ 01623 01624 /* 01625 * Descendants of class Exception are used to communicate between 01626 * Kernel#raise and +rescue+ statements in <code>begin ... end</code> blocks. 01627 * Exception objects carry information about the exception -- its type (the 01628 * exception's class name), an optional descriptive string, and optional 01629 * traceback information. Exception subclasses may add additional 01630 * information like NameError#name. 01631 * 01632 * Programs may make subclasses of Exception, typically of StandardError or 01633 * RuntimeError, to provide custom classes and add additional information. 01634 * See the subclass list below for defaults for +raise+ and +rescue+. 01635 * 01636 * When an exception has been raised but not yet handled (in +rescue+, 01637 * +ensure+, +at_exit+ and +END+ blocks) the global variable <code>$!</code> 01638 * will contain the current exception and <code>$@</code> contains the 01639 * current exception's backtrace. 01640 * 01641 * It is recommended that a library should have one subclass of StandardError 01642 * or RuntimeError and have specific exception types inherit from it. This 01643 * allows the user to rescue a generic exception type to catch all exceptions 01644 * the library may raise even if future versions of the library add new 01645 * exception subclasses. 01646 * 01647 * For example: 01648 * 01649 * class MyLibrary 01650 * class Error < RuntimeError 01651 * end 01652 * 01653 * class WidgetError < Error 01654 * end 01655 * 01656 * class FrobError < Error 01657 * end 01658 * 01659 * end 01660 * 01661 * To handle both WidgetError and FrobError the library user can rescue 01662 * MyLibrary::Error. 01663 * 01664 * The built-in subclasses of Exception are: 01665 * 01666 * * NoMemoryError 01667 * * ScriptError 01668 * * LoadError 01669 * * NotImplementedError 01670 * * SyntaxError 01671 * * SignalException 01672 * * Interrupt 01673 * * StandardError -- default for +rescue+ 01674 * * ArgumentError 01675 * * IndexError 01676 * * StopIteration 01677 * * IOError 01678 * * EOFError 01679 * * LocalJumpError 01680 * * NameError 01681 * * NoMethodError 01682 * * RangeError 01683 * * FloatDomainError 01684 * * RegexpError 01685 * * RuntimeError -- default for +raise+ 01686 * * SecurityError 01687 * * SystemCallError 01688 * * Errno::* 01689 * * SystemStackError 01690 * * ThreadError 01691 * * TypeError 01692 * * ZeroDivisionError 01693 * * SystemExit 01694 * * fatal -- impossible to rescue 01695 */ 01696 01697 void 01698 Init_Exception(void) 01699 { 01700 rb_eException = rb_define_class("Exception", rb_cObject); 01701 rb_define_singleton_method(rb_eException, "exception", rb_class_new_instance, -1); 01702 rb_define_method(rb_eException, "exception", exc_exception, -1); 01703 rb_define_method(rb_eException, "initialize", exc_initialize, -1); 01704 rb_define_method(rb_eException, "==", exc_equal, 1); 01705 rb_define_method(rb_eException, "to_s", exc_to_s, 0); 01706 rb_define_method(rb_eException, "message", exc_message, 0); 01707 rb_define_method(rb_eException, "inspect", exc_inspect, 0); 01708 rb_define_method(rb_eException, "backtrace", exc_backtrace, 0); 01709 rb_define_method(rb_eException, "set_backtrace", exc_set_backtrace, 1); 01710 01711 rb_eSystemExit = rb_define_class("SystemExit", rb_eException); 01712 rb_define_method(rb_eSystemExit, "initialize", exit_initialize, -1); 01713 rb_define_method(rb_eSystemExit, "status", exit_status, 0); 01714 rb_define_method(rb_eSystemExit, "success?", exit_success_p, 0); 01715 01716 rb_eFatal = rb_define_class("fatal", rb_eException); 01717 rb_eSignal = rb_define_class("SignalException", rb_eException); 01718 rb_eInterrupt = rb_define_class("Interrupt", rb_eSignal); 01719 01720 rb_eStandardError = rb_define_class("StandardError", rb_eException); 01721 rb_eTypeError = rb_define_class("TypeError", rb_eStandardError); 01722 rb_eArgError = rb_define_class("ArgumentError", rb_eStandardError); 01723 rb_eIndexError = rb_define_class("IndexError", rb_eStandardError); 01724 rb_eKeyError = rb_define_class("KeyError", rb_eIndexError); 01725 rb_eRangeError = rb_define_class("RangeError", rb_eStandardError); 01726 01727 rb_eScriptError = rb_define_class("ScriptError", rb_eException); 01728 rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError); 01729 01730 rb_eLoadError = rb_define_class("LoadError", rb_eScriptError); 01731 rb_attr(rb_eLoadError, rb_intern("path"), 1, 0, Qfalse); 01732 01733 rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError); 01734 01735 rb_eNameError = rb_define_class("NameError", rb_eStandardError); 01736 rb_define_method(rb_eNameError, "initialize", name_err_initialize, -1); 01737 rb_define_method(rb_eNameError, "name", name_err_name, 0); 01738 rb_define_method(rb_eNameError, "to_s", name_err_to_s, 0); 01739 rb_cNameErrorMesg = rb_define_class_under(rb_eNameError, "message", rb_cData); 01740 rb_define_singleton_method(rb_cNameErrorMesg, "!", rb_name_err_mesg_new, NAME_ERR_MESG_COUNT); 01741 rb_define_method(rb_cNameErrorMesg, "==", name_err_mesg_equal, 1); 01742 rb_define_method(rb_cNameErrorMesg, "to_str", name_err_mesg_to_str, 0); 01743 rb_define_method(rb_cNameErrorMesg, "_dump", name_err_mesg_dump, 1); 01744 rb_define_singleton_method(rb_cNameErrorMesg, "_load", name_err_mesg_load, 1); 01745 rb_eNoMethodError = rb_define_class("NoMethodError", rb_eNameError); 01746 rb_define_method(rb_eNoMethodError, "initialize", nometh_err_initialize, -1); 01747 rb_define_method(rb_eNoMethodError, "args", nometh_err_args, 0); 01748 01749 rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError); 01750 rb_eSecurityError = rb_define_class("SecurityError", rb_eException); 01751 rb_eNoMemError = rb_define_class("NoMemoryError", rb_eException); 01752 rb_eEncodingError = rb_define_class("EncodingError", rb_eStandardError); 01753 rb_eEncCompatError = rb_define_class_under(rb_cEncoding, "CompatibilityError", rb_eEncodingError); 01754 01755 syserr_tbl = st_init_numtable(); 01756 rb_eSystemCallError = rb_define_class("SystemCallError", rb_eStandardError); 01757 rb_define_method(rb_eSystemCallError, "initialize", syserr_initialize, -1); 01758 rb_define_method(rb_eSystemCallError, "errno", syserr_errno, 0); 01759 rb_define_singleton_method(rb_eSystemCallError, "===", syserr_eqq, 1); 01760 01761 rb_mErrno = rb_define_module("Errno"); 01762 01763 rb_define_global_function("warn", rb_warn_m, -1); 01764 } 01765 01766 void 01767 rb_enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...) 01768 { 01769 va_list args; 01770 VALUE mesg; 01771 01772 va_start(args, fmt); 01773 mesg = rb_enc_vsprintf(enc, fmt, args); 01774 va_end(args); 01775 01776 rb_exc_raise(rb_exc_new3(exc, mesg)); 01777 } 01778 01779 void 01780 rb_raise(VALUE exc, const char *fmt, ...) 01781 { 01782 va_list args; 01783 VALUE mesg; 01784 01785 va_start(args, fmt); 01786 mesg = rb_vsprintf(fmt, args); 01787 va_end(args); 01788 rb_exc_raise(rb_exc_new3(exc, mesg)); 01789 } 01790 01791 NORETURN(static void raise_loaderror(VALUE path, VALUE mesg)); 01792 01793 static void 01794 raise_loaderror(VALUE path, VALUE mesg) 01795 { 01796 VALUE err = rb_exc_new3(rb_eLoadError, mesg); 01797 rb_ivar_set(err, rb_intern("@path"), path); 01798 rb_exc_raise(err); 01799 } 01800 01801 void 01802 rb_loaderror(const char *fmt, ...) 01803 { 01804 va_list args; 01805 VALUE mesg; 01806 01807 va_start(args, fmt); 01808 mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args); 01809 va_end(args); 01810 raise_loaderror(Qnil, mesg); 01811 } 01812 01813 void 01814 rb_loaderror_with_path(VALUE path, const char *fmt, ...) 01815 { 01816 va_list args; 01817 VALUE mesg; 01818 01819 va_start(args, fmt); 01820 mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args); 01821 va_end(args); 01822 raise_loaderror(path, mesg); 01823 } 01824 01825 void 01826 rb_notimplement(void) 01827 { 01828 rb_raise(rb_eNotImpError, 01829 "%s() function is unimplemented on this machine", 01830 rb_id2name(rb_frame_this_func())); 01831 } 01832 01833 void 01834 rb_fatal(const char *fmt, ...) 01835 { 01836 va_list args; 01837 VALUE mesg; 01838 01839 va_start(args, fmt); 01840 mesg = rb_vsprintf(fmt, args); 01841 va_end(args); 01842 01843 rb_exc_fatal(rb_exc_new3(rb_eFatal, mesg)); 01844 } 01845 01846 static VALUE 01847 make_errno_exc(const char *mesg) 01848 { 01849 int n = errno; 01850 01851 errno = 0; 01852 if (n == 0) { 01853 rb_bug("rb_sys_fail(%s) - errno == 0", mesg ? mesg : ""); 01854 } 01855 return rb_syserr_new(n, mesg); 01856 } 01857 01858 static VALUE 01859 make_errno_exc_str(VALUE mesg) 01860 { 01861 int n = errno; 01862 01863 errno = 0; 01864 if (!mesg) mesg = Qnil; 01865 if (n == 0) { 01866 const char *s = !NIL_P(mesg) ? RSTRING_PTR(mesg) : ""; 01867 rb_bug("rb_sys_fail_str(%s) - errno == 0", s); 01868 } 01869 return rb_syserr_new_str(n, mesg); 01870 } 01871 01872 VALUE 01873 rb_syserr_new(int n, const char *mesg) 01874 { 01875 VALUE arg; 01876 arg = mesg ? rb_str_new2(mesg) : Qnil; 01877 return rb_syserr_new_str(n, arg); 01878 } 01879 01880 VALUE 01881 rb_syserr_new_str(int n, VALUE arg) 01882 { 01883 return rb_class_new_instance(1, &arg, get_syserr(n)); 01884 } 01885 01886 void 01887 rb_syserr_fail(int e, const char *mesg) 01888 { 01889 rb_exc_raise(rb_syserr_new(e, mesg)); 01890 } 01891 01892 void 01893 rb_syserr_fail_str(int e, VALUE mesg) 01894 { 01895 rb_exc_raise(rb_syserr_new_str(e, mesg)); 01896 } 01897 01898 void 01899 rb_sys_fail(const char *mesg) 01900 { 01901 rb_exc_raise(make_errno_exc(mesg)); 01902 } 01903 01904 void 01905 rb_sys_fail_str(VALUE mesg) 01906 { 01907 rb_exc_raise(make_errno_exc_str(mesg)); 01908 } 01909 01910 void 01911 rb_mod_sys_fail(VALUE mod, const char *mesg) 01912 { 01913 VALUE exc = make_errno_exc(mesg); 01914 rb_extend_object(exc, mod); 01915 rb_exc_raise(exc); 01916 } 01917 01918 void 01919 rb_mod_sys_fail_str(VALUE mod, VALUE mesg) 01920 { 01921 VALUE exc = make_errno_exc_str(mesg); 01922 rb_extend_object(exc, mod); 01923 rb_exc_raise(exc); 01924 } 01925 01926 void 01927 rb_mod_syserr_fail(VALUE mod, int e, const char *mesg) 01928 { 01929 VALUE exc = rb_syserr_new(e, mesg); 01930 rb_extend_object(exc, mod); 01931 rb_exc_raise(exc); 01932 } 01933 01934 void 01935 rb_mod_syserr_fail_str(VALUE mod, int e, VALUE mesg) 01936 { 01937 VALUE exc = rb_syserr_new_str(e, mesg); 01938 rb_extend_object(exc, mod); 01939 rb_exc_raise(exc); 01940 } 01941 01942 void 01943 rb_sys_warning(const char *fmt, ...) 01944 { 01945 char buf[BUFSIZ]; 01946 va_list args; 01947 int errno_save; 01948 01949 errno_save = errno; 01950 01951 if (!RTEST(ruby_verbose)) return; 01952 01953 snprintf(buf, BUFSIZ, "warning: %s", fmt); 01954 snprintf(buf+strlen(buf), BUFSIZ-strlen(buf), ": %s", strerror(errno_save)); 01955 01956 va_start(args, fmt); 01957 warn_print(buf, args); 01958 va_end(args); 01959 errno = errno_save; 01960 } 01961 01962 void 01963 rb_load_fail(VALUE path, const char *err) 01964 { 01965 VALUE mesg = rb_str_buf_new_cstr(err); 01966 rb_str_cat2(mesg, " -- "); 01967 rb_str_append(mesg, path); /* should be ASCII compatible */ 01968 raise_loaderror(path, mesg); 01969 } 01970 01971 void 01972 rb_error_frozen(const char *what) 01973 { 01974 rb_raise(rb_eRuntimeError, "can't modify frozen %s", what); 01975 } 01976 01977 #undef rb_check_frozen 01978 void 01979 rb_check_frozen(VALUE obj) 01980 { 01981 rb_check_frozen_internal(obj); 01982 } 01983 01984 void 01985 rb_error_untrusted(VALUE obj) 01986 { 01987 if (rb_safe_level() >= 4) { 01988 rb_raise(rb_eSecurityError, "Insecure: can't modify %s", 01989 rb_obj_classname(obj)); 01990 } 01991 } 01992 01993 #undef rb_check_trusted 01994 void 01995 rb_check_trusted(VALUE obj) 01996 { 01997 rb_check_trusted_internal(obj); 01998 } 01999 02000 void 02001 rb_check_copyable(VALUE obj, VALUE orig) 02002 { 02003 if (!FL_ABLE(obj)) return; 02004 rb_check_frozen_internal(obj); 02005 rb_check_trusted_internal(obj); 02006 if (!FL_ABLE(orig)) return; 02007 if ((~RBASIC(obj)->flags & RBASIC(orig)->flags) & (FL_UNTRUSTED|FL_TAINT)) { 02008 if (rb_safe_level() > 0) { 02009 rb_raise(rb_eSecurityError, "Insecure: can't modify %"PRIsVALUE, 02010 RBASIC(obj)->klass); 02011 } 02012 } 02013 } 02014 02015 void 02016 Init_syserr(void) 02017 { 02018 rb_eNOERROR = set_syserr(0, "NOERROR"); 02019 #define defined_error(name, num) set_syserr((num), (name)); 02020 #define undefined_error(name) set_syserr(0, (name)); 02021 #include "known_errors.inc" 02022 #undef defined_error 02023 #undef undefined_error 02024 } 02025