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