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 "vm_core.h"
00016
00017 #include <stdio.h>
00018 #include <stdarg.h>
00019 #ifdef HAVE_STDLIB_H
00020 #include <stdlib.h>
00021 #endif
00022 #include <errno.h>
00023
00024 #ifndef EXIT_SUCCESS
00025 #define EXIT_SUCCESS 0
00026 #endif
00027
00028 extern const char ruby_description[];
00029
00030 static const char *
00031 rb_strerrno(int err)
00032 {
00033 #define defined_error(name, num) if (err == num) return name;
00034 #define undefined_error(name)
00035 #include "known_errors.inc"
00036 #undef defined_error
00037 #undef undefined_error
00038 return NULL;
00039 }
00040
00041 static int
00042 err_position_0(char *buf, long len, const char *file, int line)
00043 {
00044 if (!file) {
00045 return 0;
00046 }
00047 else if (line == 0) {
00048 return snprintf(buf, len, "%s: ", file);
00049 }
00050 else {
00051 return snprintf(buf, len, "%s:%d: ", file, line);
00052 }
00053 }
00054
00055 static int
00056 err_position(char *buf, long len)
00057 {
00058 return err_position_0(buf, len, rb_sourcefile(), rb_sourceline());
00059 }
00060
00061 static void
00062 err_snprintf(char *buf, long len, const char *fmt, va_list args)
00063 {
00064 long n;
00065
00066 n = err_position(buf, len);
00067 if (len > n) {
00068 vsnprintf((char*)buf+n, len-n, fmt, args);
00069 }
00070 }
00071
00072 static void
00073 compile_snprintf(char *buf, long len, const char *file, int line, const char *fmt, va_list args)
00074 {
00075 long n;
00076
00077 n = err_position_0(buf, len, file, line);
00078 if (len > n) {
00079 vsnprintf((char*)buf+n, len-n, fmt, args);
00080 }
00081 }
00082
00083 static void err_append(const char*);
00084
00085 void
00086 rb_compile_error(const char *file, int line, const char *fmt, ...)
00087 {
00088 va_list args;
00089 char buf[BUFSIZ];
00090
00091 va_start(args, fmt);
00092 compile_snprintf(buf, BUFSIZ, file, line, fmt, args);
00093 va_end(args);
00094 err_append(buf);
00095 }
00096
00097 void
00098 rb_compile_error_append(const char *fmt, ...)
00099 {
00100 va_list args;
00101 char buf[BUFSIZ];
00102
00103 va_start(args, fmt);
00104 vsnprintf(buf, BUFSIZ, fmt, args);
00105 va_end(args);
00106 err_append(buf);
00107 }
00108
00109 static void
00110 compile_warn_print(const char *file, int line, const char *fmt, va_list args)
00111 {
00112 char buf[BUFSIZ];
00113 int len;
00114
00115 compile_snprintf(buf, BUFSIZ, file, line, fmt, args);
00116 len = (int)strlen(buf);
00117 buf[len++] = '\n';
00118 rb_write_error2(buf, len);
00119 }
00120
00121 void
00122 rb_compile_warn(const char *file, int line, const char *fmt, ...)
00123 {
00124 char buf[BUFSIZ];
00125 va_list args;
00126
00127 if (NIL_P(ruby_verbose)) return;
00128
00129 snprintf(buf, BUFSIZ, "warning: %s", fmt);
00130
00131 va_start(args, fmt);
00132 compile_warn_print(file, line, buf, args);
00133 va_end(args);
00134 }
00135
00136
00137 void
00138 rb_compile_warning(const char *file, int line, const char *fmt, ...)
00139 {
00140 char buf[BUFSIZ];
00141 va_list args;
00142
00143 if (!RTEST(ruby_verbose)) return;
00144
00145 snprintf(buf, BUFSIZ, "warning: %s", fmt);
00146
00147 va_start(args, fmt);
00148 compile_warn_print(file, line, buf, args);
00149 va_end(args);
00150 }
00151
00152 static void
00153 warn_print(const char *fmt, va_list args)
00154 {
00155 char buf[BUFSIZ];
00156 int len;
00157
00158 err_snprintf(buf, BUFSIZ, fmt, args);
00159 len = (int)strlen(buf);
00160 buf[len++] = '\n';
00161 rb_write_error2(buf, len);
00162 }
00163
00164 void
00165 rb_warn(const char *fmt, ...)
00166 {
00167 char buf[BUFSIZ];
00168 va_list args;
00169
00170 if (NIL_P(ruby_verbose)) return;
00171
00172 snprintf(buf, BUFSIZ, "warning: %s", fmt);
00173
00174 va_start(args, fmt);
00175 warn_print(buf, args);
00176 va_end(args);
00177 }
00178
00179
00180 void
00181 rb_warning(const char *fmt, ...)
00182 {
00183 char buf[BUFSIZ];
00184 va_list args;
00185
00186 if (!RTEST(ruby_verbose)) return;
00187
00188 snprintf(buf, BUFSIZ, "warning: %s", fmt);
00189
00190 va_start(args, fmt);
00191 warn_print(buf, args);
00192 va_end(args);
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 static VALUE
00204 rb_warn_m(VALUE self, VALUE mesg)
00205 {
00206 if (!NIL_P(ruby_verbose)) {
00207 rb_io_write(rb_stderr, mesg);
00208 rb_io_write(rb_stderr, rb_default_rs);
00209 }
00210 return Qnil;
00211 }
00212
00213 void rb_vm_bugreport(void);
00214
00215 static void
00216 report_bug(const char *file, int line, const char *fmt, va_list args)
00217 {
00218 char buf[BUFSIZ];
00219 FILE *out = stderr;
00220 int len = err_position_0(buf, BUFSIZ, file, line);
00221
00222 if ((ssize_t)fwrite(buf, 1, len, out) == (ssize_t)len ||
00223 (ssize_t)fwrite(buf, 1, len, (out = stdout)) == (ssize_t)len) {
00224
00225 fputs("[BUG] ", out);
00226 vfprintf(out, fmt, args);
00227 fprintf(out, "\n%s\n\n", ruby_description);
00228
00229 rb_vm_bugreport();
00230
00231 fprintf(out,
00232 "[NOTE]\n"
00233 "You may have encountered a bug in the Ruby interpreter"
00234 " or extension libraries.\n"
00235 "Bug reports are welcome.\n"
00236 "For details: http://www.ruby-lang.org/bugreport.html\n\n");
00237 }
00238 }
00239
00240 void
00241 rb_bug(const char *fmt, ...)
00242 {
00243 va_list args;
00244
00245 va_start(args, fmt);
00246 report_bug(rb_sourcefile(), rb_sourceline(), fmt, args);
00247 va_end(args);
00248
00249 #if defined(_WIN32) && defined(RT_VER) && RT_VER >= 80
00250 _set_abort_behavior( 0, _CALL_REPORTFAULT);
00251 #endif
00252
00253 abort();
00254 }
00255
00256 void
00257 rb_bug_errno(const char *mesg, int errno_arg)
00258 {
00259 if (errno_arg == 0)
00260 rb_bug("%s: errno == 0 (NOERROR)", mesg);
00261 else {
00262 const char *errno_str = rb_strerrno(errno_arg);
00263 if (errno_str)
00264 rb_bug("%s: %s (%s)", mesg, strerror(errno_arg), errno_str);
00265 else
00266 rb_bug("%s: %s (%d)", mesg, strerror(errno_arg), errno_arg);
00267 }
00268 }
00269
00270 void
00271 rb_compile_bug(const char *file, int line, const char *fmt, ...)
00272 {
00273 va_list args;
00274
00275 va_start(args, fmt);
00276 report_bug(file, line, fmt, args);
00277 va_end(args);
00278
00279 abort();
00280 }
00281
00282 static const struct types {
00283 int type;
00284 const char *name;
00285 } builtin_types[] = {
00286 {T_NIL, "nil"},
00287 {T_OBJECT, "Object"},
00288 {T_CLASS, "Class"},
00289 {T_ICLASS, "iClass"},
00290 {T_MODULE, "Module"},
00291 {T_FLOAT, "Float"},
00292 {T_STRING, "String"},
00293 {T_REGEXP, "Regexp"},
00294 {T_ARRAY, "Array"},
00295 {T_FIXNUM, "Fixnum"},
00296 {T_HASH, "Hash"},
00297 {T_STRUCT, "Struct"},
00298 {T_BIGNUM, "Bignum"},
00299 {T_FILE, "File"},
00300 {T_RATIONAL,"Rational"},
00301 {T_COMPLEX, "Complex"},
00302 {T_TRUE, "true"},
00303 {T_FALSE, "false"},
00304 {T_SYMBOL, "Symbol"},
00305 {T_DATA, "Data"},
00306 {T_MATCH, "MatchData"},
00307 {T_NODE, "Node"},
00308 {T_UNDEF, "undef"},
00309 };
00310
00311 void
00312 rb_check_type(VALUE x, int t)
00313 {
00314 const struct types *type = builtin_types;
00315 const struct types *const typeend = builtin_types +
00316 sizeof(builtin_types) / sizeof(builtin_types[0]);
00317 int xt;
00318
00319 if (x == Qundef) {
00320 rb_bug("undef leaked to the Ruby space");
00321 }
00322
00323 xt = TYPE(x);
00324 if (xt != t || (xt == T_DATA && RTYPEDDATA_P(x))) {
00325 while (type < typeend) {
00326 if (type->type == t) {
00327 const char *etype;
00328
00329 if (NIL_P(x)) {
00330 etype = "nil";
00331 }
00332 else if (FIXNUM_P(x)) {
00333 etype = "Fixnum";
00334 }
00335 else if (SYMBOL_P(x)) {
00336 etype = "Symbol";
00337 }
00338 else if (rb_special_const_p(x)) {
00339 etype = RSTRING_PTR(rb_obj_as_string(x));
00340 }
00341 else {
00342 etype = rb_obj_classname(x);
00343 }
00344 rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
00345 etype, type->name);
00346 }
00347 type++;
00348 }
00349 rb_bug("unknown type 0x%x (0x%x given)", t, TYPE(x));
00350 }
00351 }
00352
00353 int
00354 rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
00355 {
00356 if (SPECIAL_CONST_P(obj) || BUILTIN_TYPE(obj) != T_DATA ||
00357 !RTYPEDDATA_P(obj) || RTYPEDDATA_TYPE(obj) != data_type) {
00358 return 0;
00359 }
00360 return 1;
00361 }
00362
00363 void *
00364 rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
00365 {
00366 const char *etype;
00367 static const char mesg[] = "wrong argument type %s (expected %s)";
00368
00369 if (SPECIAL_CONST_P(obj) || BUILTIN_TYPE(obj) != T_DATA) {
00370 Check_Type(obj, T_DATA);
00371 }
00372 if (!RTYPEDDATA_P(obj)) {
00373 etype = rb_obj_classname(obj);
00374 rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name);
00375 }
00376 else if (RTYPEDDATA_TYPE(obj) != data_type) {
00377 etype = RTYPEDDATA_TYPE(obj)->wrap_struct_name;
00378 rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name);
00379 }
00380 return DATA_PTR(obj);
00381 }
00382
00383
00384 VALUE rb_eException;
00385 VALUE rb_eSystemExit;
00386 VALUE rb_eInterrupt;
00387 VALUE rb_eSignal;
00388 VALUE rb_eFatal;
00389 VALUE rb_eStandardError;
00390 VALUE rb_eRuntimeError;
00391 VALUE rb_eTypeError;
00392 VALUE rb_eArgError;
00393 VALUE rb_eIndexError;
00394 VALUE rb_eKeyError;
00395 VALUE rb_eRangeError;
00396 VALUE rb_eNameError;
00397 VALUE rb_eEncodingError;
00398 VALUE rb_eEncCompatError;
00399 VALUE rb_eNoMethodError;
00400 VALUE rb_eSecurityError;
00401 VALUE rb_eNotImpError;
00402 VALUE rb_eNoMemError;
00403 VALUE rb_cNameErrorMesg;
00404
00405 VALUE rb_eScriptError;
00406 VALUE rb_eSyntaxError;
00407 VALUE rb_eLoadError;
00408
00409 VALUE rb_eSystemCallError;
00410 VALUE rb_mErrno;
00411 static VALUE rb_eNOERROR;
00412
00413 #undef rb_exc_new2
00414
00415 VALUE
00416 rb_exc_new(VALUE etype, const char *ptr, long len)
00417 {
00418 return rb_funcall(etype, rb_intern("new"), 1, rb_str_new(ptr, len));
00419 }
00420
00421 VALUE
00422 rb_exc_new2(VALUE etype, const char *s)
00423 {
00424 return rb_exc_new(etype, s, strlen(s));
00425 }
00426
00427 VALUE
00428 rb_exc_new3(VALUE etype, VALUE str)
00429 {
00430 StringValue(str);
00431 return rb_funcall(etype, rb_intern("new"), 1, str);
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 static VALUE
00443 exc_initialize(int argc, VALUE *argv, VALUE exc)
00444 {
00445 VALUE arg;
00446
00447 rb_scan_args(argc, argv, "01", &arg);
00448 rb_iv_set(exc, "mesg", arg);
00449 rb_iv_set(exc, "bt", Qnil);
00450
00451 return exc;
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467 static VALUE
00468 exc_exception(int argc, VALUE *argv, VALUE self)
00469 {
00470 VALUE exc;
00471
00472 if (argc == 0) return self;
00473 if (argc == 1 && self == argv[0]) return self;
00474 exc = rb_obj_clone(self);
00475 exc_initialize(argc, argv, exc);
00476
00477 return exc;
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488 static VALUE
00489 exc_to_s(VALUE exc)
00490 {
00491 VALUE mesg = rb_attr_get(exc, rb_intern("mesg"));
00492
00493 if (NIL_P(mesg)) return rb_class_name(CLASS_OF(exc));
00494 if (OBJ_TAINTED(exc)) OBJ_TAINT(mesg);
00495 return mesg;
00496 }
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 static VALUE
00509 exc_message(VALUE exc)
00510 {
00511 return rb_funcall(exc, rb_intern("to_s"), 0, 0);
00512 }
00513
00514
00515
00516
00517
00518
00519
00520
00521 static VALUE
00522 exc_inspect(VALUE exc)
00523 {
00524 VALUE str, klass;
00525
00526 klass = CLASS_OF(exc);
00527 exc = rb_obj_as_string(exc);
00528 if (RSTRING_LEN(exc) == 0) {
00529 return rb_str_dup(rb_class_name(klass));
00530 }
00531
00532 str = rb_str_buf_new2("#<");
00533 klass = rb_class_name(klass);
00534 rb_str_buf_append(str, klass);
00535 rb_str_buf_cat(str, ": ", 2);
00536 rb_str_buf_append(str, exc);
00537 rb_str_buf_cat(str, ">", 1);
00538
00539 return str;
00540 }
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571 static VALUE
00572 exc_backtrace(VALUE exc)
00573 {
00574 ID bt;
00575
00576 CONST_ID(bt, "bt");
00577 return rb_attr_get(exc, bt);
00578 }
00579
00580 VALUE
00581 rb_check_backtrace(VALUE bt)
00582 {
00583 long i;
00584 static const char err[] = "backtrace must be Array of String";
00585
00586 if (!NIL_P(bt)) {
00587 int t = TYPE(bt);
00588
00589 if (t == T_STRING) return rb_ary_new3(1, bt);
00590 if (t != T_ARRAY) {
00591 rb_raise(rb_eTypeError, err);
00592 }
00593 for (i=0;i<RARRAY_LEN(bt);i++) {
00594 if (TYPE(RARRAY_PTR(bt)[i]) != T_STRING) {
00595 rb_raise(rb_eTypeError, err);
00596 }
00597 }
00598 }
00599 return bt;
00600 }
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612 static VALUE
00613 exc_set_backtrace(VALUE exc, VALUE bt)
00614 {
00615 return rb_iv_set(exc, "bt", rb_check_backtrace(bt));
00616 }
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 static VALUE
00628 exc_equal(VALUE exc, VALUE obj)
00629 {
00630 VALUE mesg, backtrace;
00631 ID id_mesg;
00632
00633 if (exc == obj) return Qtrue;
00634 CONST_ID(id_mesg, "mesg");
00635
00636 if (rb_obj_class(exc) != rb_obj_class(obj)) {
00637 ID id_message, id_backtrace;
00638 CONST_ID(id_message, "message");
00639 CONST_ID(id_backtrace, "backtrace");
00640
00641 mesg = rb_check_funcall(obj, id_message, 0, 0);
00642 if (mesg == Qundef) return Qfalse;
00643 backtrace = rb_check_funcall(obj, id_backtrace, 0, 0);
00644 if (backtrace == Qundef) return Qfalse;
00645 }
00646 else {
00647 mesg = rb_attr_get(obj, id_mesg);
00648 backtrace = exc_backtrace(obj);
00649 }
00650
00651 if (!rb_equal(rb_attr_get(exc, id_mesg), mesg))
00652 return Qfalse;
00653 if (!rb_equal(exc_backtrace(exc), backtrace))
00654 return Qfalse;
00655 return Qtrue;
00656 }
00657
00658
00659
00660
00661
00662
00663
00664
00665 static VALUE
00666 exit_initialize(int argc, VALUE *argv, VALUE exc)
00667 {
00668 VALUE status = INT2FIX(EXIT_SUCCESS);
00669 if (argc > 0 && FIXNUM_P(argv[0])) {
00670 status = *argv++;
00671 --argc;
00672 }
00673 rb_call_super(argc, argv);
00674 rb_iv_set(exc, "status", status);
00675 return exc;
00676 }
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686 static VALUE
00687 exit_status(VALUE exc)
00688 {
00689 return rb_attr_get(exc, rb_intern("status"));
00690 }
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700 static VALUE
00701 exit_success_p(VALUE exc)
00702 {
00703 VALUE status = rb_attr_get(exc, rb_intern("status"));
00704 if (NIL_P(status)) return Qtrue;
00705 if (status == INT2FIX(EXIT_SUCCESS)) return Qtrue;
00706 return Qfalse;
00707 }
00708
00709 void
00710 rb_name_error(ID id, const char *fmt, ...)
00711 {
00712 VALUE exc, argv[2];
00713 va_list args;
00714
00715 va_start(args, fmt);
00716 argv[0] = rb_vsprintf(fmt, args);
00717 va_end(args);
00718
00719 argv[1] = ID2SYM(id);
00720 exc = rb_class_new_instance(2, argv, rb_eNameError);
00721 rb_exc_raise(exc);
00722 }
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733 static VALUE
00734 name_err_initialize(int argc, VALUE *argv, VALUE self)
00735 {
00736 VALUE name;
00737
00738 name = (argc > 1) ? argv[--argc] : Qnil;
00739 rb_call_super(argc, argv);
00740 rb_iv_set(self, "name", name);
00741 return self;
00742 }
00743
00744
00745
00746
00747
00748
00749
00750
00751 static VALUE
00752 name_err_name(VALUE self)
00753 {
00754 return rb_attr_get(self, rb_intern("name"));
00755 }
00756
00757
00758
00759
00760
00761
00762
00763
00764 static VALUE
00765 name_err_to_s(VALUE exc)
00766 {
00767 VALUE mesg = rb_attr_get(exc, rb_intern("mesg"));
00768 VALUE str = mesg;
00769
00770 if (NIL_P(mesg)) return rb_class_name(CLASS_OF(exc));
00771 StringValue(str);
00772 if (str != mesg) {
00773 rb_iv_set(exc, "mesg", mesg = str);
00774 }
00775 if (OBJ_TAINTED(exc)) OBJ_TAINT(mesg);
00776 return mesg;
00777 }
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789 static VALUE
00790 nometh_err_initialize(int argc, VALUE *argv, VALUE self)
00791 {
00792 VALUE args = (argc > 2) ? argv[--argc] : Qnil;
00793 name_err_initialize(argc, argv, self);
00794 rb_iv_set(self, "args", args);
00795 return self;
00796 }
00797
00798
00799 #define NAME_ERR_MESG_COUNT 3
00800
00801 static void
00802 name_err_mesg_mark(void *p)
00803 {
00804 VALUE *ptr = p;
00805 rb_gc_mark_locations(ptr, ptr+NAME_ERR_MESG_COUNT);
00806 }
00807
00808 #define name_err_mesg_free RUBY_TYPED_DEFAULT_FREE
00809
00810 static size_t
00811 name_err_mesg_memsize(const void *p)
00812 {
00813 return p ? (NAME_ERR_MESG_COUNT * sizeof(VALUE)) : 0;
00814 }
00815
00816 static const rb_data_type_t name_err_mesg_data_type = {
00817 "name_err_mesg",
00818 name_err_mesg_mark,
00819 name_err_mesg_free,
00820 name_err_mesg_memsize,
00821 };
00822
00823
00824 VALUE
00825 rb_name_err_mesg_new(VALUE obj, VALUE mesg, VALUE recv, VALUE method)
00826 {
00827 VALUE *ptr = ALLOC_N(VALUE, NAME_ERR_MESG_COUNT);
00828 VALUE result;
00829
00830 ptr[0] = mesg;
00831 ptr[1] = recv;
00832 ptr[2] = method;
00833 result = TypedData_Wrap_Struct(rb_cNameErrorMesg, &name_err_mesg_data_type, ptr);
00834 RB_GC_GUARD(mesg);
00835 RB_GC_GUARD(recv);
00836 RB_GC_GUARD(method);
00837 return result;
00838 }
00839
00840
00841 static VALUE
00842 name_err_mesg_equal(VALUE obj1, VALUE obj2)
00843 {
00844 VALUE *ptr1, *ptr2;
00845 int i;
00846
00847 if (obj1 == obj2) return Qtrue;
00848 if (rb_obj_class(obj2) != rb_cNameErrorMesg)
00849 return Qfalse;
00850
00851 TypedData_Get_Struct(obj1, VALUE, &name_err_mesg_data_type, ptr1);
00852 TypedData_Get_Struct(obj2, VALUE, &name_err_mesg_data_type, ptr2);
00853 for (i=0; i<NAME_ERR_MESG_COUNT; i++) {
00854 if (!rb_equal(ptr1[i], ptr2[i]))
00855 return Qfalse;
00856 }
00857 return Qtrue;
00858 }
00859
00860
00861 static VALUE
00862 name_err_mesg_to_str(VALUE obj)
00863 {
00864 VALUE *ptr, mesg;
00865 TypedData_Get_Struct(obj, VALUE, &name_err_mesg_data_type, ptr);
00866
00867 mesg = ptr[0];
00868 if (NIL_P(mesg)) return Qnil;
00869 else {
00870 const char *desc = 0;
00871 VALUE d = 0, args[NAME_ERR_MESG_COUNT];
00872
00873 obj = ptr[1];
00874 switch (TYPE(obj)) {
00875 case T_NIL:
00876 desc = "nil";
00877 break;
00878 case T_TRUE:
00879 desc = "true";
00880 break;
00881 case T_FALSE:
00882 desc = "false";
00883 break;
00884 default:
00885 d = rb_protect(rb_inspect, obj, 0);
00886 if (NIL_P(d) || RSTRING_LEN(d) > 65) {
00887 d = rb_any_to_s(obj);
00888 }
00889 desc = RSTRING_PTR(d);
00890 break;
00891 }
00892 if (desc && desc[0] != '#') {
00893 d = d ? rb_str_dup(d) : rb_str_new2(desc);
00894 rb_str_cat2(d, ":");
00895 rb_str_cat2(d, rb_obj_classname(obj));
00896 }
00897 args[0] = mesg;
00898 args[1] = ptr[2];
00899 args[2] = d;
00900 mesg = rb_f_sprintf(NAME_ERR_MESG_COUNT, args);
00901 }
00902 if (OBJ_TAINTED(obj)) OBJ_TAINT(mesg);
00903 return mesg;
00904 }
00905
00906
00907 static VALUE
00908 name_err_mesg_load(VALUE klass, VALUE str)
00909 {
00910 return str;
00911 }
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921 static VALUE
00922 nometh_err_args(VALUE self)
00923 {
00924 return rb_attr_get(self, rb_intern("args"));
00925 }
00926
00927 void
00928 rb_invalid_str(const char *str, const char *type)
00929 {
00930 VALUE s = rb_str_inspect(rb_str_new2(str));
00931
00932 rb_raise(rb_eArgError, "invalid value for %s: %s", type, RSTRING_PTR(s));
00933 }
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966 static st_table *syserr_tbl;
00967
00968 static VALUE
00969 set_syserr(int n, const char *name)
00970 {
00971 VALUE error;
00972
00973 if (!st_lookup(syserr_tbl, n, &error)) {
00974 error = rb_define_class_under(rb_mErrno, name, rb_eSystemCallError);
00975 rb_define_const(error, "Errno", INT2NUM(n));
00976 st_add_direct(syserr_tbl, n, error);
00977 }
00978 else {
00979 rb_define_const(rb_mErrno, name, error);
00980 }
00981 return error;
00982 }
00983
00984 static VALUE
00985 get_syserr(int n)
00986 {
00987 VALUE error;
00988
00989 if (!st_lookup(syserr_tbl, n, &error)) {
00990 char name[8];
00991
00992 snprintf(name, sizeof(name), "E%03d", n);
00993 error = set_syserr(n, name);
00994 }
00995 return error;
00996 }
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009 static VALUE
01010 syserr_initialize(int argc, VALUE *argv, VALUE self)
01011 {
01012 #if !defined(_WIN32)
01013 char *strerror();
01014 #endif
01015 const char *err;
01016 VALUE mesg, error;
01017 VALUE klass = rb_obj_class(self);
01018
01019 if (klass == rb_eSystemCallError) {
01020 rb_scan_args(argc, argv, "11", &mesg, &error);
01021 if (argc == 1 && FIXNUM_P(mesg)) {
01022 error = mesg; mesg = Qnil;
01023 }
01024 if (!NIL_P(error) && st_lookup(syserr_tbl, NUM2LONG(error), &klass)) {
01025
01026 if (TYPE(self) != T_OBJECT) {
01027 rb_raise(rb_eTypeError, "invalid instance type");
01028 }
01029 RBASIC(self)->klass = klass;
01030 }
01031 }
01032 else {
01033 rb_scan_args(argc, argv, "01", &mesg);
01034 error = rb_const_get(klass, rb_intern("Errno"));
01035 }
01036 if (!NIL_P(error)) err = strerror(NUM2INT(error));
01037 else err = "unknown error";
01038 if (!NIL_P(mesg)) {
01039 VALUE str = mesg;
01040
01041 StringValue(str);
01042 mesg = rb_sprintf("%s - %.*s", err,
01043 (int)RSTRING_LEN(str), RSTRING_PTR(str));
01044 }
01045 else {
01046 mesg = rb_str_new2(err);
01047 }
01048 rb_call_super(1, &mesg);
01049 rb_iv_set(self, "errno", error);
01050 return self;
01051 }
01052
01053
01054
01055
01056
01057
01058
01059
01060 static VALUE
01061 syserr_errno(VALUE self)
01062 {
01063 return rb_attr_get(self, rb_intern("errno"));
01064 }
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074 static VALUE
01075 syserr_eqq(VALUE self, VALUE exc)
01076 {
01077 VALUE num, e;
01078 ID en;
01079
01080 CONST_ID(en, "errno");
01081
01082 if (!rb_obj_is_kind_of(exc, rb_eSystemCallError)) {
01083 if (!rb_respond_to(exc, en)) return Qfalse;
01084 }
01085 else if (self == rb_eSystemCallError) return Qtrue;
01086
01087 num = rb_attr_get(exc, rb_intern("errno"));
01088 if (NIL_P(num)) {
01089 num = rb_funcall(exc, en, 0, 0);
01090 }
01091 e = rb_const_get(self, rb_intern("Errno"));
01092 if (FIXNUM_P(num) ? num == e : rb_equal(num, e))
01093 return Qtrue;
01094 return Qfalse;
01095 }
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
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
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
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 void
01398 Init_Exception(void)
01399 {
01400 rb_eException = rb_define_class("Exception", rb_cObject);
01401 rb_define_singleton_method(rb_eException, "exception", rb_class_new_instance, -1);
01402 rb_define_method(rb_eException, "exception", exc_exception, -1);
01403 rb_define_method(rb_eException, "initialize", exc_initialize, -1);
01404 rb_define_method(rb_eException, "==", exc_equal, 1);
01405 rb_define_method(rb_eException, "to_s", exc_to_s, 0);
01406 rb_define_method(rb_eException, "message", exc_message, 0);
01407 rb_define_method(rb_eException, "inspect", exc_inspect, 0);
01408 rb_define_method(rb_eException, "backtrace", exc_backtrace, 0);
01409 rb_define_method(rb_eException, "set_backtrace", exc_set_backtrace, 1);
01410
01411 rb_eSystemExit = rb_define_class("SystemExit", rb_eException);
01412 rb_define_method(rb_eSystemExit, "initialize", exit_initialize, -1);
01413 rb_define_method(rb_eSystemExit, "status", exit_status, 0);
01414 rb_define_method(rb_eSystemExit, "success?", exit_success_p, 0);
01415
01416 rb_eFatal = rb_define_class("fatal", rb_eException);
01417 rb_eSignal = rb_define_class("SignalException", rb_eException);
01418 rb_eInterrupt = rb_define_class("Interrupt", rb_eSignal);
01419
01420 rb_eStandardError = rb_define_class("StandardError", rb_eException);
01421 rb_eTypeError = rb_define_class("TypeError", rb_eStandardError);
01422 rb_eArgError = rb_define_class("ArgumentError", rb_eStandardError);
01423 rb_eIndexError = rb_define_class("IndexError", rb_eStandardError);
01424 rb_eKeyError = rb_define_class("KeyError", rb_eIndexError);
01425 rb_eRangeError = rb_define_class("RangeError", rb_eStandardError);
01426
01427 rb_eScriptError = rb_define_class("ScriptError", rb_eException);
01428 rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError);
01429 rb_eLoadError = rb_define_class("LoadError", rb_eScriptError);
01430 rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError);
01431
01432 rb_eNameError = rb_define_class("NameError", rb_eStandardError);
01433 rb_define_method(rb_eNameError, "initialize", name_err_initialize, -1);
01434 rb_define_method(rb_eNameError, "name", name_err_name, 0);
01435 rb_define_method(rb_eNameError, "to_s", name_err_to_s, 0);
01436 rb_cNameErrorMesg = rb_define_class_under(rb_eNameError, "message", rb_cData);
01437 rb_define_singleton_method(rb_cNameErrorMesg, "!", rb_name_err_mesg_new, NAME_ERR_MESG_COUNT);
01438 rb_define_method(rb_cNameErrorMesg, "==", name_err_mesg_equal, 1);
01439 rb_define_method(rb_cNameErrorMesg, "to_str", name_err_mesg_to_str, 0);
01440 rb_define_method(rb_cNameErrorMesg, "_dump", name_err_mesg_to_str, 1);
01441 rb_define_singleton_method(rb_cNameErrorMesg, "_load", name_err_mesg_load, 1);
01442 rb_eNoMethodError = rb_define_class("NoMethodError", rb_eNameError);
01443 rb_define_method(rb_eNoMethodError, "initialize", nometh_err_initialize, -1);
01444 rb_define_method(rb_eNoMethodError, "args", nometh_err_args, 0);
01445
01446 rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError);
01447 rb_eSecurityError = rb_define_class("SecurityError", rb_eException);
01448 rb_eNoMemError = rb_define_class("NoMemoryError", rb_eException);
01449 rb_eEncodingError = rb_define_class("EncodingError", rb_eStandardError);
01450 rb_eEncCompatError = rb_define_class_under(rb_cEncoding, "CompatibilityError", rb_eEncodingError);
01451
01452 syserr_tbl = st_init_numtable();
01453 rb_eSystemCallError = rb_define_class("SystemCallError", rb_eStandardError);
01454 rb_define_method(rb_eSystemCallError, "initialize", syserr_initialize, -1);
01455 rb_define_method(rb_eSystemCallError, "errno", syserr_errno, 0);
01456 rb_define_singleton_method(rb_eSystemCallError, "===", syserr_eqq, 1);
01457
01458 rb_mErrno = rb_define_module("Errno");
01459
01460 rb_define_global_function("warn", rb_warn_m, 1);
01461 }
01462
01463 void
01464 rb_raise(VALUE exc, const char *fmt, ...)
01465 {
01466 va_list args;
01467 VALUE mesg;
01468
01469 va_start(args, fmt);
01470 mesg = rb_vsprintf(fmt, args);
01471 va_end(args);
01472 rb_exc_raise(rb_exc_new3(exc, mesg));
01473 }
01474
01475 void
01476 rb_loaderror(const char *fmt, ...)
01477 {
01478 va_list args;
01479 VALUE mesg;
01480
01481 va_start(args, fmt);
01482 mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args);
01483 va_end(args);
01484 rb_exc_raise(rb_exc_new3(rb_eLoadError, mesg));
01485 }
01486
01487 void
01488 rb_notimplement(void)
01489 {
01490 rb_raise(rb_eNotImpError,
01491 "%s() function is unimplemented on this machine",
01492 rb_id2name(rb_frame_this_func()));
01493 }
01494
01495 void
01496 rb_fatal(const char *fmt, ...)
01497 {
01498 va_list args;
01499 VALUE mesg;
01500
01501 va_start(args, fmt);
01502 mesg = rb_vsprintf(fmt, args);
01503 va_end(args);
01504
01505 rb_exc_fatal(rb_exc_new3(rb_eFatal, mesg));
01506 }
01507
01508 static VALUE
01509 make_errno_exc(const char *mesg)
01510 {
01511 int n = errno;
01512 VALUE arg;
01513
01514 errno = 0;
01515 if (n == 0) {
01516 rb_bug("rb_sys_fail(%s) - errno == 0", mesg ? mesg : "");
01517 }
01518
01519 arg = mesg ? rb_str_new2(mesg) : Qnil;
01520 return rb_class_new_instance(1, &arg, get_syserr(n));
01521 }
01522
01523 void
01524 rb_sys_fail(const char *mesg)
01525 {
01526 rb_exc_raise(make_errno_exc(mesg));
01527 }
01528
01529 void
01530 rb_mod_sys_fail(VALUE mod, const char *mesg)
01531 {
01532 VALUE exc = make_errno_exc(mesg);
01533 rb_extend_object(exc, mod);
01534 rb_exc_raise(exc);
01535 }
01536
01537 void
01538 rb_sys_warning(const char *fmt, ...)
01539 {
01540 char buf[BUFSIZ];
01541 va_list args;
01542 int errno_save;
01543
01544 errno_save = errno;
01545
01546 if (!RTEST(ruby_verbose)) return;
01547
01548 snprintf(buf, BUFSIZ, "warning: %s", fmt);
01549 snprintf(buf+strlen(buf), BUFSIZ-strlen(buf), ": %s", strerror(errno_save));
01550
01551 va_start(args, fmt);
01552 warn_print(buf, args);
01553 va_end(args);
01554 errno = errno_save;
01555 }
01556
01557 void
01558 rb_load_fail(const char *path)
01559 {
01560 rb_loaderror("%s -- %s", strerror(errno), path);
01561 }
01562
01563 void
01564 rb_error_frozen(const char *what)
01565 {
01566 rb_raise(rb_eRuntimeError, "can't modify frozen %s", what);
01567 }
01568
01569 void
01570 rb_check_frozen(VALUE obj)
01571 {
01572 if (OBJ_FROZEN(obj)) rb_error_frozen(rb_obj_classname(obj));
01573 }
01574
01575 void
01576 Init_syserr(void)
01577 {
01578 rb_eNOERROR = set_syserr(0, "NOERROR");
01579 #define defined_error(name, num) set_syserr(num, name);
01580 #define undefined_error(name) set_syserr(0, name);
01581 #include "known_errors.inc"
01582 #undef defined_error
01583 #undef undefined_error
01584 }
01585
01586 static void
01587 err_append(const char *s)
01588 {
01589 rb_thread_t *th = GET_THREAD();
01590 VALUE err = th->errinfo;
01591
01592 if (th->mild_compile_error) {
01593 if (!RTEST(err)) {
01594 err = rb_exc_new2(rb_eSyntaxError, s);
01595 th->errinfo = err;
01596 }
01597 else {
01598 VALUE str = rb_obj_as_string(err);
01599
01600 rb_str_cat2(str, "\n");
01601 rb_str_cat2(str, s);
01602 th->errinfo = rb_exc_new3(rb_eSyntaxError, str);
01603 }
01604 }
01605 else {
01606 if (!RTEST(err)) {
01607 err = rb_exc_new2(rb_eSyntaxError, "compile error");
01608 th->errinfo = err;
01609 }
01610 rb_write_error(s);
01611 rb_write_error("\n");
01612 }
01613 }
01614