00001
00002
00003
00004
00005
00006
00007
00008
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
00104
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
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
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
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
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
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
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
00333
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 "",
00376 "Object",
00377 "Class",
00378 "Module",
00379 "Float",
00380 "String",
00381 "Regexp",
00382 "Array",
00383 "Hash",
00384 "Struct",
00385 "Bignum",
00386 "File",
00387 "Data",
00388 "MatchData",
00389 "Complex",
00390 "Rational",
00391 "",
00392 "nil",
00393 "true",
00394 "false",
00395 "Symbol",
00396 "Fixnum",
00397 "",
00398 "",
00399 "",
00400 "",
00401 "",
00402 "undef",
00403 "Node",
00404 "iClass",
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
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
00561
00562
00563
00564
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
00581
00582
00583
00584
00585
00586
00587
00588
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
00607
00608
00609
00610
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
00626
00627
00628
00629
00630
00631
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
00642
00643
00644
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
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
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
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
00737
00738
00739
00740
00741
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
00767
00768
00769
00770
00771
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
00814
00815
00816
00817
00818
00819
00820
00821
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
00869
00870
00871
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
00883
00884
00885
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
00935
00936
00937
00938
00939
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
00955
00956
00957
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
00968
00969
00970
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
00986
00987
00988
00989
00990
00991
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
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
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
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
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
01116 static VALUE
01117 name_err_mesg_dump(VALUE obj, VALUE limit)
01118 {
01119 return name_err_mesg_to_str(obj);
01120 }
01121
01122
01123 static VALUE
01124 name_err_mesg_load(VALUE klass, VALUE str)
01125 {
01126 return str;
01127 }
01128
01129
01130
01131
01132
01133
01134
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
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
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];
01207
01208 snprintf(name, sizeof(name), "E%03d", n);
01209 error = set_syserr(n, name);
01210 }
01211 return error;
01212 }
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
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
01244 if (!RB_TYPE_P(self, T_OBJECT)) {
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 }
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
01279
01280
01281
01282
01283
01284 static VALUE
01285 syserr_errno(VALUE self)
01286 {
01287 return rb_attr_get(self, rb_intern("errno"));
01288 }
01289
01290
01291
01292
01293
01294
01295
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
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
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);
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