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