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