error.c

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

Generated on 19 Jul 2016 for Ruby by  doxygen 1.4.7