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