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