PageRenderTime 60ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/ruby/error.c

http://android-ruby.googlecode.com/
C | 1218 lines | 811 code | 179 blank | 228 comment | 116 complexity | 35ff52da7e237206ecd1066f40027ffc MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-3.0, 0BSD, Unlicense, GPL-2.0, BSD-3-Clause
  1. /**********************************************************************
  2. error.c -
  3. $Author: yugui $
  4. created at: Mon Aug 9 16:11:34 JST 1993
  5. Copyright (C) 1993-2007 Yukihiro Matsumoto
  6. **********************************************************************/
  7. #include "ruby/ruby.h"
  8. #include "ruby/st.h"
  9. #include "vm_core.h"
  10. #include <stdio.h>
  11. #include <stdarg.h>
  12. #ifdef HAVE_STDLIB_H
  13. #include <stdlib.h>
  14. #endif
  15. #ifndef EXIT_SUCCESS
  16. #define EXIT_SUCCESS 0
  17. #endif
  18. extern const char ruby_description[];
  19. static int
  20. err_position_0(char *buf, long len, const char *file, int line)
  21. {
  22. if (!file) {
  23. return 0;
  24. }
  25. else if (line == 0) {
  26. return snprintf(buf, len, "%s: ", file);
  27. }
  28. else {
  29. return snprintf(buf, len, "%s:%d: ", file, line);
  30. }
  31. }
  32. static int
  33. err_position(char *buf, long len)
  34. {
  35. return err_position_0(buf, len, rb_sourcefile(), rb_sourceline());
  36. }
  37. static void
  38. err_snprintf(char *buf, long len, const char *fmt, va_list args)
  39. {
  40. long n;
  41. n = err_position(buf, len);
  42. if (len > n) {
  43. vsnprintf((char*)buf+n, len-n, fmt, args);
  44. }
  45. }
  46. static void
  47. compile_snprintf(char *buf, long len, const char *file, int line, const char *fmt, va_list args)
  48. {
  49. long n;
  50. n = err_position_0(buf, len, file, line);
  51. if (len > n) {
  52. vsnprintf((char*)buf+n, len-n, fmt, args);
  53. }
  54. }
  55. static void err_append(const char*);
  56. void
  57. rb_compile_error(const char *file, int line, const char *fmt, ...)
  58. {
  59. va_list args;
  60. char buf[BUFSIZ];
  61. va_start(args, fmt);
  62. compile_snprintf(buf, BUFSIZ, file, line, fmt, args);
  63. va_end(args);
  64. err_append(buf);
  65. }
  66. void
  67. rb_compile_error_append(const char *fmt, ...)
  68. {
  69. va_list args;
  70. char buf[BUFSIZ];
  71. va_start(args, fmt);
  72. vsnprintf(buf, BUFSIZ, fmt, args);
  73. va_end(args);
  74. err_append(buf);
  75. }
  76. static void
  77. compile_warn_print(const char *file, int line, const char *fmt, va_list args)
  78. {
  79. char buf[BUFSIZ];
  80. int len;
  81. compile_snprintf(buf, BUFSIZ, file, line, fmt, args);
  82. len = strlen(buf);
  83. buf[len++] = '\n';
  84. rb_write_error2(buf, len);
  85. }
  86. void
  87. rb_compile_warn(const char *file, int line, const char *fmt, ...)
  88. {
  89. char buf[BUFSIZ];
  90. va_list args;
  91. if (NIL_P(ruby_verbose)) return;
  92. snprintf(buf, BUFSIZ, "warning: %s", fmt);
  93. va_start(args, fmt);
  94. compile_warn_print(file, line, buf, args);
  95. va_end(args);
  96. }
  97. /* rb_compile_warning() reports only in verbose mode */
  98. void
  99. rb_compile_warning(const char *file, int line, const char *fmt, ...)
  100. {
  101. char buf[BUFSIZ];
  102. va_list args;
  103. if (!RTEST(ruby_verbose)) return;
  104. snprintf(buf, BUFSIZ, "warning: %s", fmt);
  105. va_start(args, fmt);
  106. compile_warn_print(file, line, buf, args);
  107. va_end(args);
  108. }
  109. static void
  110. warn_print(const char *fmt, va_list args)
  111. {
  112. char buf[BUFSIZ];
  113. int len;
  114. err_snprintf(buf, BUFSIZ, fmt, args);
  115. len = strlen(buf);
  116. buf[len++] = '\n';
  117. rb_write_error2(buf, len);
  118. }
  119. void
  120. rb_warn(const char *fmt, ...)
  121. {
  122. char buf[BUFSIZ];
  123. va_list args;
  124. if (NIL_P(ruby_verbose)) return;
  125. snprintf(buf, BUFSIZ, "warning: %s", fmt);
  126. va_start(args, fmt);
  127. warn_print(buf, args);
  128. va_end(args);
  129. }
  130. /* rb_warning() reports only in verbose mode */
  131. void
  132. rb_warning(const char *fmt, ...)
  133. {
  134. char buf[BUFSIZ];
  135. va_list args;
  136. if (!RTEST(ruby_verbose)) return;
  137. snprintf(buf, BUFSIZ, "warning: %s", fmt);
  138. va_start(args, fmt);
  139. warn_print(buf, args);
  140. va_end(args);
  141. }
  142. /*
  143. * call-seq:
  144. * warn(msg) => nil
  145. *
  146. * Display the given message (followed by a newline) on STDERR unless
  147. * warnings are disabled (for example with the <code>-W0</code> flag).
  148. */
  149. static VALUE
  150. rb_warn_m(VALUE self, VALUE mesg)
  151. {
  152. if (!NIL_P(ruby_verbose)) {
  153. rb_io_write(rb_stderr, mesg);
  154. rb_io_write(rb_stderr, rb_default_rs);
  155. }
  156. return Qnil;
  157. }
  158. void rb_vm_bugreport(void);
  159. static void
  160. report_bug(const char *file, int line, const char *fmt, va_list args)
  161. {
  162. char buf[BUFSIZ];
  163. FILE *out = stderr;
  164. int len = err_position_0(buf, BUFSIZ, file, line);
  165. if (fwrite(buf, 1, len, out) == len ||
  166. fwrite(buf, 1, len, (out = stdout)) == len) {
  167. fputs("[BUG] ", out);
  168. vfprintf(out, fmt, args);
  169. fprintf(out, "\n%s\n\n", ruby_description);
  170. rb_vm_bugreport();
  171. fprintf(out,
  172. "[NOTE]\n"
  173. "You may encounter a bug of Ruby interpreter. Bug reports are welcome.\n"
  174. "For details: http://www.ruby-lang.org/bugreport.html\n\n");
  175. }
  176. }
  177. void
  178. rb_bug(const char *fmt, ...)
  179. {
  180. va_list args;
  181. va_start(args, fmt);
  182. report_bug(rb_sourcefile(), rb_sourceline(), fmt, args);
  183. va_end(args);
  184. abort();
  185. }
  186. void
  187. rb_compile_bug(const char *file, int line, const char *fmt, ...)
  188. {
  189. va_list args;
  190. va_start(args, fmt);
  191. report_bug(file, line, fmt, args);
  192. va_end(args);
  193. abort();
  194. }
  195. static const struct types {
  196. int type;
  197. const char *name;
  198. } builtin_types[] = {
  199. {T_NIL, "nil"},
  200. {T_OBJECT, "Object"},
  201. {T_CLASS, "Class"},
  202. {T_ICLASS, "iClass"}, /* internal use: mixed-in module holder */
  203. {T_MODULE, "Module"},
  204. {T_FLOAT, "Float"},
  205. {T_STRING, "String"},
  206. {T_REGEXP, "Regexp"},
  207. {T_ARRAY, "Array"},
  208. {T_FIXNUM, "Fixnum"},
  209. {T_HASH, "Hash"},
  210. {T_STRUCT, "Struct"},
  211. {T_BIGNUM, "Bignum"},
  212. {T_FILE, "File"},
  213. {T_RATIONAL,"Rational"},
  214. {T_COMPLEX, "Complex"},
  215. {T_TRUE, "true"},
  216. {T_FALSE, "false"},
  217. {T_SYMBOL, "Symbol"}, /* :symbol */
  218. {T_DATA, "Data"}, /* internal use: wrapped C pointers */
  219. {T_MATCH, "MatchData"}, /* data of $~ */
  220. {T_NODE, "Node"}, /* internal use: syntax tree node */
  221. {T_UNDEF, "undef"}, /* internal use: #undef; should not happen */
  222. };
  223. void
  224. rb_check_type(VALUE x, int t)
  225. {
  226. const struct types *type = builtin_types;
  227. const struct types *const typeend = builtin_types +
  228. sizeof(builtin_types) / sizeof(builtin_types[0]);
  229. if (x == Qundef) {
  230. rb_bug("undef leaked to the Ruby space");
  231. }
  232. if (TYPE(x) != t) {
  233. while (type < typeend) {
  234. if (type->type == t) {
  235. const char *etype;
  236. if (NIL_P(x)) {
  237. etype = "nil";
  238. }
  239. else if (FIXNUM_P(x)) {
  240. etype = "Fixnum";
  241. }
  242. else if (SYMBOL_P(x)) {
  243. etype = "Symbol";
  244. }
  245. else if (rb_special_const_p(x)) {
  246. etype = RSTRING_PTR(rb_obj_as_string(x));
  247. }
  248. else {
  249. etype = rb_obj_classname(x);
  250. }
  251. rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
  252. etype, type->name);
  253. }
  254. type++;
  255. }
  256. rb_bug("unknown type 0x%x (0x%x given)", t, TYPE(x));
  257. }
  258. }
  259. /* exception classes */
  260. #include <errno.h>
  261. VALUE rb_eException;
  262. VALUE rb_eSystemExit;
  263. VALUE rb_eInterrupt;
  264. VALUE rb_eSignal;
  265. VALUE rb_eFatal;
  266. VALUE rb_eStandardError;
  267. VALUE rb_eRuntimeError;
  268. VALUE rb_eTypeError;
  269. VALUE rb_eArgError;
  270. VALUE rb_eIndexError;
  271. VALUE rb_eKeyError;
  272. VALUE rb_eRangeError;
  273. VALUE rb_eNameError;
  274. VALUE rb_eEncodingError;
  275. VALUE rb_eEncCompatError;
  276. VALUE rb_eNoMethodError;
  277. VALUE rb_eSecurityError;
  278. VALUE rb_eNotImpError;
  279. VALUE rb_eNoMemError;
  280. VALUE rb_cNameErrorMesg;
  281. VALUE rb_eScriptError;
  282. VALUE rb_eSyntaxError;
  283. VALUE rb_eLoadError;
  284. VALUE rb_eSystemCallError;
  285. VALUE rb_mErrno;
  286. static VALUE rb_eNOERROR;
  287. VALUE
  288. rb_exc_new(VALUE etype, const char *ptr, long len)
  289. {
  290. return rb_funcall(etype, rb_intern("new"), 1, rb_str_new(ptr, len));
  291. }
  292. VALUE
  293. rb_exc_new2(VALUE etype, const char *s)
  294. {
  295. return rb_exc_new(etype, s, strlen(s));
  296. }
  297. VALUE
  298. rb_exc_new3(VALUE etype, VALUE str)
  299. {
  300. StringValue(str);
  301. return rb_funcall(etype, rb_intern("new"), 1, str);
  302. }
  303. /*
  304. * call-seq:
  305. * Exception.new(msg = nil) => exception
  306. *
  307. * Construct a new Exception object, optionally passing in
  308. * a message.
  309. */
  310. static VALUE
  311. exc_initialize(int argc, VALUE *argv, VALUE exc)
  312. {
  313. VALUE arg;
  314. rb_scan_args(argc, argv, "01", &arg);
  315. rb_iv_set(exc, "mesg", arg);
  316. rb_iv_set(exc, "bt", Qnil);
  317. return exc;
  318. }
  319. /*
  320. * Document-method: exception
  321. *
  322. * call-seq:
  323. * exc.exception(string) -> an_exception or exc
  324. *
  325. * With no argument, or if the argument is the same as the receiver,
  326. * return the receiver. Otherwise, create a new
  327. * exception object of the same class as the receiver, but with a
  328. * message equal to <code>string.to_str</code>.
  329. *
  330. */
  331. static VALUE
  332. exc_exception(int argc, VALUE *argv, VALUE self)
  333. {
  334. VALUE exc;
  335. if (argc == 0) return self;
  336. if (argc == 1 && self == argv[0]) return self;
  337. exc = rb_obj_clone(self);
  338. exc_initialize(argc, argv, exc);
  339. return exc;
  340. }
  341. /*
  342. * call-seq:
  343. * exception.to_s => string
  344. *
  345. * Returns exception's message (or the name of the exception if
  346. * no message is set).
  347. */
  348. static VALUE
  349. exc_to_s(VALUE exc)
  350. {
  351. VALUE mesg = rb_attr_get(exc, rb_intern("mesg"));
  352. if (NIL_P(mesg)) return rb_class_name(CLASS_OF(exc));
  353. if (OBJ_TAINTED(exc)) OBJ_TAINT(mesg);
  354. return mesg;
  355. }
  356. /*
  357. * call-seq:
  358. * exception.message => string
  359. *
  360. * Returns the result of invoking <code>exception.to_s</code>.
  361. * Normally this returns the exception's message or name. By
  362. * supplying a to_str method, exceptions are agreeing to
  363. * be used where Strings are expected.
  364. */
  365. static VALUE
  366. exc_message(VALUE exc)
  367. {
  368. return rb_funcall(exc, rb_intern("to_s"), 0, 0);
  369. }
  370. /*
  371. * call-seq:
  372. * exception.inspect => string
  373. *
  374. * Return this exception's class name an message
  375. */
  376. static VALUE
  377. exc_inspect(VALUE exc)
  378. {
  379. VALUE str, klass;
  380. klass = CLASS_OF(exc);
  381. exc = rb_obj_as_string(exc);
  382. if (RSTRING_LEN(exc) == 0) {
  383. return rb_str_dup(rb_class_name(klass));
  384. }
  385. str = rb_str_buf_new2("#<");
  386. klass = rb_class_name(klass);
  387. rb_str_buf_append(str, klass);
  388. rb_str_buf_cat(str, ": ", 2);
  389. rb_str_buf_append(str, exc);
  390. rb_str_buf_cat(str, ">", 1);
  391. return str;
  392. }
  393. /*
  394. * call-seq:
  395. * exception.backtrace => array
  396. *
  397. * Returns any backtrace associated with the exception. The backtrace
  398. * is an array of strings, each containing either ``filename:lineNo: in
  399. * `method''' or ``filename:lineNo.''
  400. *
  401. * def a
  402. * raise "boom"
  403. * end
  404. *
  405. * def b
  406. * a()
  407. * end
  408. *
  409. * begin
  410. * b()
  411. * rescue => detail
  412. * print detail.backtrace.join("\n")
  413. * end
  414. *
  415. * <em>produces:</em>
  416. *
  417. * prog.rb:2:in `a'
  418. * prog.rb:6:in `b'
  419. * prog.rb:10
  420. */
  421. static VALUE
  422. exc_backtrace(VALUE exc)
  423. {
  424. ID bt;
  425. CONST_ID(bt, "bt");
  426. return rb_attr_get(exc, bt);
  427. }
  428. VALUE
  429. rb_check_backtrace(VALUE bt)
  430. {
  431. long i;
  432. static const char err[] = "backtrace must be Array of String";
  433. if (!NIL_P(bt)) {
  434. int t = TYPE(bt);
  435. if (t == T_STRING) return rb_ary_new3(1, bt);
  436. if (t != T_ARRAY) {
  437. rb_raise(rb_eTypeError, err);
  438. }
  439. for (i=0;i<RARRAY_LEN(bt);i++) {
  440. if (TYPE(RARRAY_PTR(bt)[i]) != T_STRING) {
  441. rb_raise(rb_eTypeError, err);
  442. }
  443. }
  444. }
  445. return bt;
  446. }
  447. /*
  448. * call-seq:
  449. * exc.set_backtrace(array) => array
  450. *
  451. * Sets the backtrace information associated with <i>exc</i>. The
  452. * argument must be an array of <code>String</code> objects in the
  453. * format described in <code>Exception#backtrace</code>.
  454. *
  455. */
  456. static VALUE
  457. exc_set_backtrace(VALUE exc, VALUE bt)
  458. {
  459. return rb_iv_set(exc, "bt", rb_check_backtrace(bt));
  460. }
  461. /*
  462. * call-seq:
  463. * exc == obj => true or false
  464. *
  465. * Equality---If <i>obj</i> is not an <code>Exception</code>, returns
  466. * <code>false</code>. Otherwise, returns <code>true</code> if <i>exc</i> and
  467. * <i>obj</i> share same class, messages, and backtrace.
  468. */
  469. static VALUE
  470. exc_equal(VALUE exc, VALUE obj)
  471. {
  472. VALUE mesg, backtrace;
  473. ID id_mesg;
  474. if (exc == obj) return Qtrue;
  475. CONST_ID(id_mesg, "mesg");
  476. if (rb_obj_class(exc) != rb_obj_class(obj)) {
  477. ID id_message, id_backtrace;
  478. CONST_ID(id_message, "message");
  479. CONST_ID(id_backtrace, "backtrace");
  480. if (rb_respond_to(obj, id_message) && rb_respond_to(obj, id_backtrace)) {
  481. mesg = rb_funcall(obj, id_message, 0, 0);
  482. backtrace = rb_funcall(obj, id_backtrace, 0, 0);
  483. }
  484. else {
  485. return Qfalse;
  486. }
  487. }
  488. else {
  489. mesg = rb_attr_get(obj, id_mesg);
  490. backtrace = exc_backtrace(obj);
  491. }
  492. if (!rb_equal(rb_attr_get(exc, id_mesg), mesg))
  493. return Qfalse;
  494. if (!rb_equal(exc_backtrace(exc), backtrace))
  495. return Qfalse;
  496. return Qtrue;
  497. }
  498. /*
  499. * call-seq:
  500. * SystemExit.new(status=0) => system_exit
  501. *
  502. * Create a new +SystemExit+ exception with the given status.
  503. */
  504. static VALUE
  505. exit_initialize(int argc, VALUE *argv, VALUE exc)
  506. {
  507. VALUE status = INT2FIX(EXIT_SUCCESS);
  508. if (argc > 0 && FIXNUM_P(argv[0])) {
  509. status = *argv++;
  510. --argc;
  511. }
  512. rb_call_super(argc, argv);
  513. rb_iv_set(exc, "status", status);
  514. return exc;
  515. }
  516. /*
  517. * call-seq:
  518. * system_exit.status => fixnum
  519. *
  520. * Return the status value associated with this system exit.
  521. */
  522. static VALUE
  523. exit_status(VALUE exc)
  524. {
  525. return rb_attr_get(exc, rb_intern("status"));
  526. }
  527. /*
  528. * call-seq:
  529. * system_exit.success? => true or false
  530. *
  531. * Returns +true+ if exiting successful, +false+ if not.
  532. */
  533. static VALUE
  534. exit_success_p(VALUE exc)
  535. {
  536. VALUE status = rb_attr_get(exc, rb_intern("status"));
  537. if (NIL_P(status)) return Qtrue;
  538. if (status == INT2FIX(EXIT_SUCCESS)) return Qtrue;
  539. return Qfalse;
  540. }
  541. void
  542. rb_name_error(ID id, const char *fmt, ...)
  543. {
  544. VALUE exc, argv[2];
  545. va_list args;
  546. va_start(args, fmt);
  547. argv[0] = rb_vsprintf(fmt, args);
  548. va_end(args);
  549. argv[1] = ID2SYM(id);
  550. exc = rb_class_new_instance(2, argv, rb_eNameError);
  551. rb_exc_raise(exc);
  552. }
  553. /*
  554. * call-seq:
  555. * NameError.new(msg [, name]) => name_error
  556. *
  557. * Construct a new NameError exception. If given the <i>name</i>
  558. * parameter may subsequently be examined using the <code>NameError.name</code>
  559. * method.
  560. */
  561. static VALUE
  562. name_err_initialize(int argc, VALUE *argv, VALUE self)
  563. {
  564. VALUE name;
  565. name = (argc > 1) ? argv[--argc] : Qnil;
  566. rb_call_super(argc, argv);
  567. rb_iv_set(self, "name", name);
  568. return self;
  569. }
  570. /*
  571. * call-seq:
  572. * name_error.name => string or nil
  573. *
  574. * Return the name associated with this NameError exception.
  575. */
  576. static VALUE
  577. name_err_name(VALUE self)
  578. {
  579. return rb_attr_get(self, rb_intern("name"));
  580. }
  581. /*
  582. * call-seq:
  583. * name_error.to_s => string
  584. *
  585. * Produce a nicely-formatted string representing the +NameError+.
  586. */
  587. static VALUE
  588. name_err_to_s(VALUE exc)
  589. {
  590. VALUE mesg = rb_attr_get(exc, rb_intern("mesg"));
  591. VALUE str = mesg;
  592. if (NIL_P(mesg)) return rb_class_name(CLASS_OF(exc));
  593. StringValue(str);
  594. if (str != mesg) {
  595. rb_iv_set(exc, "mesg", mesg = str);
  596. }
  597. if (OBJ_TAINTED(exc)) OBJ_TAINT(mesg);
  598. return mesg;
  599. }
  600. /*
  601. * call-seq:
  602. * NoMethodError.new(msg, name [, args]) => no_method_error
  603. *
  604. * Construct a NoMethodError exception for a method of the given name
  605. * called with the given arguments. The name may be accessed using
  606. * the <code>#name</code> method on the resulting object, and the
  607. * arguments using the <code>#args</code> method.
  608. */
  609. static VALUE
  610. nometh_err_initialize(int argc, VALUE *argv, VALUE self)
  611. {
  612. VALUE args = (argc > 2) ? argv[--argc] : Qnil;
  613. name_err_initialize(argc, argv, self);
  614. rb_iv_set(self, "args", args);
  615. return self;
  616. }
  617. /* :nodoc: */
  618. static void
  619. name_err_mesg_mark(VALUE *ptr)
  620. {
  621. rb_gc_mark_locations(ptr, ptr+3);
  622. }
  623. /* :nodoc: */
  624. static VALUE
  625. name_err_mesg_new(VALUE obj, VALUE mesg, VALUE recv, VALUE method)
  626. {
  627. VALUE *ptr = ALLOC_N(VALUE, 3);
  628. ptr[0] = mesg;
  629. ptr[1] = recv;
  630. ptr[2] = method;
  631. return Data_Wrap_Struct(rb_cNameErrorMesg, name_err_mesg_mark, -1, ptr);
  632. }
  633. /* :nodoc: */
  634. static VALUE
  635. name_err_mesg_equal(VALUE obj1, VALUE obj2)
  636. {
  637. VALUE *ptr1, *ptr2;
  638. int i;
  639. if (obj1 == obj2) return Qtrue;
  640. if (rb_obj_class(obj2) != rb_cNameErrorMesg)
  641. return Qfalse;
  642. Data_Get_Struct(obj1, VALUE, ptr1);
  643. Data_Get_Struct(obj2, VALUE, ptr2);
  644. for (i=0; i<3; i++) {
  645. if (!rb_equal(ptr1[i], ptr2[i]))
  646. return Qfalse;
  647. }
  648. return Qtrue;
  649. }
  650. /* :nodoc: */
  651. static VALUE
  652. name_err_mesg_to_str(VALUE obj)
  653. {
  654. VALUE *ptr, mesg;
  655. Data_Get_Struct(obj, VALUE, ptr);
  656. mesg = ptr[0];
  657. if (NIL_P(mesg)) return Qnil;
  658. else {
  659. const char *desc = 0;
  660. VALUE d = 0, args[3];
  661. obj = ptr[1];
  662. switch (TYPE(obj)) {
  663. case T_NIL:
  664. desc = "nil";
  665. break;
  666. case T_TRUE:
  667. desc = "true";
  668. break;
  669. case T_FALSE:
  670. desc = "false";
  671. break;
  672. default:
  673. d = rb_protect(rb_inspect, obj, 0);
  674. if (NIL_P(d) || RSTRING_LEN(d) > 65) {
  675. d = rb_any_to_s(obj);
  676. }
  677. desc = RSTRING_PTR(d);
  678. break;
  679. }
  680. if (desc && desc[0] != '#') {
  681. d = rb_str_new2(desc);
  682. rb_str_cat2(d, ":");
  683. rb_str_cat2(d, rb_obj_classname(obj));
  684. }
  685. args[0] = mesg;
  686. args[1] = ptr[2];
  687. args[2] = d;
  688. mesg = rb_f_sprintf(3, args);
  689. }
  690. if (OBJ_TAINTED(obj)) OBJ_TAINT(mesg);
  691. return mesg;
  692. }
  693. /* :nodoc: */
  694. static VALUE
  695. name_err_mesg_load(VALUE klass, VALUE str)
  696. {
  697. return str;
  698. }
  699. /*
  700. * call-seq:
  701. * no_method_error.args => obj
  702. *
  703. * Return the arguments passed in as the third parameter to
  704. * the constructor.
  705. */
  706. static VALUE
  707. nometh_err_args(VALUE self)
  708. {
  709. return rb_attr_get(self, rb_intern("args"));
  710. }
  711. void
  712. rb_invalid_str(const char *str, const char *type)
  713. {
  714. VALUE s = rb_str_inspect(rb_str_new2(str));
  715. rb_raise(rb_eArgError, "invalid value for %s: %s", type, RSTRING_PTR(s));
  716. }
  717. /*
  718. * Document-module: Errno
  719. *
  720. * Ruby exception objects are subclasses of <code>Exception</code>.
  721. * However, operating systems typically report errors using plain
  722. * integers. Module <code>Errno</code> is created dynamically to map
  723. * these operating system errors to Ruby classes, with each error
  724. * number generating its own subclass of <code>SystemCallError</code>.
  725. * As the subclass is created in module <code>Errno</code>, its name
  726. * will start <code>Errno::</code>.
  727. *
  728. * The names of the <code>Errno::</code> classes depend on
  729. * the environment in which Ruby runs. On a typical Unix or Windows
  730. * platform, there are <code>Errno</code> classes such as
  731. * <code>Errno::EACCES</code>, <code>Errno::EAGAIN</code>,
  732. * <code>Errno::EINTR</code>, and so on.
  733. *
  734. * The integer operating system error number corresponding to a
  735. * particular error is available as the class constant
  736. * <code>Errno::</code><em>error</em><code>::Errno</code>.
  737. *
  738. * Errno::EACCES::Errno #=> 13
  739. * Errno::EAGAIN::Errno #=> 11
  740. * Errno::EINTR::Errno #=> 4
  741. *
  742. * The full list of operating system errors on your particular platform
  743. * are available as the constants of <code>Errno</code>.
  744. *
  745. * Errno.constants #=> :E2BIG, :EACCES, :EADDRINUSE, :EADDRNOTAVAIL, ...
  746. */
  747. static st_table *syserr_tbl;
  748. static VALUE
  749. set_syserr(int n, const char *name)
  750. {
  751. VALUE error;
  752. if (!st_lookup(syserr_tbl, n, &error)) {
  753. error = rb_define_class_under(rb_mErrno, name, rb_eSystemCallError);
  754. rb_define_const(error, "Errno", INT2NUM(n));
  755. st_add_direct(syserr_tbl, n, error);
  756. }
  757. else {
  758. rb_define_const(rb_mErrno, name, error);
  759. }
  760. return error;
  761. }
  762. static VALUE
  763. get_syserr(int n)
  764. {
  765. VALUE error;
  766. if (!st_lookup(syserr_tbl, n, &error)) {
  767. char name[8]; /* some Windows' errno have 5 digits. */
  768. snprintf(name, sizeof(name), "E%03d", n);
  769. error = set_syserr(n, name);
  770. }
  771. return error;
  772. }
  773. /*
  774. * call-seq:
  775. * SystemCallError.new(msg, errno) => system_call_error_subclass
  776. *
  777. * If _errno_ corresponds to a known system error code, constructs
  778. * the appropriate <code>Errno</code> class for that error, otherwise
  779. * constructs a generic <code>SystemCallError</code> object. The
  780. * error number is subsequently available via the <code>errno</code>
  781. * method.
  782. */
  783. static VALUE
  784. syserr_initialize(int argc, VALUE *argv, VALUE self)
  785. {
  786. #if !defined(_WIN32)
  787. char *strerror();
  788. #endif
  789. const char *err;
  790. VALUE mesg, error;
  791. VALUE klass = rb_obj_class(self);
  792. if (klass == rb_eSystemCallError) {
  793. rb_scan_args(argc, argv, "11", &mesg, &error);
  794. if (argc == 1 && FIXNUM_P(mesg)) {
  795. error = mesg; mesg = Qnil;
  796. }
  797. if (!NIL_P(error) && st_lookup(syserr_tbl, NUM2LONG(error), &klass)) {
  798. /* change class */
  799. if (TYPE(self) != T_OBJECT) { /* insurance to avoid type crash */
  800. rb_raise(rb_eTypeError, "invalid instance type");
  801. }
  802. RBASIC(self)->klass = klass;
  803. }
  804. }
  805. else {
  806. rb_scan_args(argc, argv, "01", &mesg);
  807. error = rb_const_get(klass, rb_intern("Errno"));
  808. }
  809. if (!NIL_P(error)) err = strerror(NUM2LONG(error));
  810. else err = "unknown error";
  811. if (!NIL_P(mesg)) {
  812. VALUE str = mesg;
  813. StringValue(str);
  814. mesg = rb_sprintf("%s - %.*s", err,
  815. (int)RSTRING_LEN(str), RSTRING_PTR(str));
  816. }
  817. else {
  818. mesg = rb_str_new2(err);
  819. }
  820. rb_call_super(1, &mesg);
  821. rb_iv_set(self, "errno", error);
  822. return self;
  823. }
  824. /*
  825. * call-seq:
  826. * system_call_error.errno => fixnum
  827. *
  828. * Return this SystemCallError's error number.
  829. */
  830. static VALUE
  831. syserr_errno(VALUE self)
  832. {
  833. return rb_attr_get(self, rb_intern("errno"));
  834. }
  835. /*
  836. * call-seq:
  837. * system_call_error === other => true or false
  838. *
  839. * Return +true+ if the receiver is a generic +SystemCallError+, or
  840. * if the error numbers _self_ and _other_ are the same.
  841. */
  842. static VALUE
  843. syserr_eqq(VALUE self, VALUE exc)
  844. {
  845. VALUE num, e;
  846. ID en;
  847. CONST_ID(en, "errno");
  848. if (!rb_obj_is_kind_of(exc, rb_eSystemCallError)) {
  849. if (!rb_respond_to(exc, en)) return Qfalse;
  850. }
  851. else if (self == rb_eSystemCallError) return Qtrue;
  852. num = rb_attr_get(exc, rb_intern("errno"));
  853. if (NIL_P(num)) {
  854. num = rb_funcall(exc, en, 0, 0);
  855. }
  856. e = rb_const_get(self, rb_intern("Errno"));
  857. if (FIXNUM_P(num) ? num == e : rb_equal(num, e))
  858. return Qtrue;
  859. return Qfalse;
  860. }
  861. /*
  862. * Descendants of class <code>Exception</code> are used to communicate
  863. * between <code>raise</code> methods and <code>rescue</code>
  864. * statements in <code>begin/end</code> blocks. <code>Exception</code>
  865. * objects carry information about the exception---its type (the
  866. * exception's class name), an optional descriptive string, and
  867. * optional traceback information. Programs may subclass
  868. * <code>Exception</code> to add additional information.
  869. */
  870. void
  871. Init_Exception(void)
  872. {
  873. rb_eException = rb_define_class("Exception", rb_cObject);
  874. rb_define_singleton_method(rb_eException, "exception", rb_class_new_instance, -1);
  875. rb_define_method(rb_eException, "exception", exc_exception, -1);
  876. rb_define_method(rb_eException, "initialize", exc_initialize, -1);
  877. rb_define_method(rb_eException, "==", exc_equal, 1);
  878. rb_define_method(rb_eException, "to_s", exc_to_s, 0);
  879. rb_define_method(rb_eException, "message", exc_message, 0);
  880. rb_define_method(rb_eException, "inspect", exc_inspect, 0);
  881. rb_define_method(rb_eException, "backtrace", exc_backtrace, 0);
  882. rb_define_method(rb_eException, "set_backtrace", exc_set_backtrace, 1);
  883. rb_eSystemExit = rb_define_class("SystemExit", rb_eException);
  884. rb_define_method(rb_eSystemExit, "initialize", exit_initialize, -1);
  885. rb_define_method(rb_eSystemExit, "status", exit_status, 0);
  886. rb_define_method(rb_eSystemExit, "success?", exit_success_p, 0);
  887. rb_eFatal = rb_define_class("fatal", rb_eException);
  888. rb_eSignal = rb_define_class("SignalException", rb_eException);
  889. rb_eInterrupt = rb_define_class("Interrupt", rb_eSignal);
  890. rb_eStandardError = rb_define_class("StandardError", rb_eException);
  891. rb_eTypeError = rb_define_class("TypeError", rb_eStandardError);
  892. rb_eArgError = rb_define_class("ArgumentError", rb_eStandardError);
  893. rb_eIndexError = rb_define_class("IndexError", rb_eStandardError);
  894. rb_eKeyError = rb_define_class("KeyError", rb_eIndexError);
  895. rb_eRangeError = rb_define_class("RangeError", rb_eStandardError);
  896. rb_eScriptError = rb_define_class("ScriptError", rb_eException);
  897. rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError);
  898. rb_eLoadError = rb_define_class("LoadError", rb_eScriptError);
  899. rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError);
  900. rb_eNameError = rb_define_class("NameError", rb_eStandardError);
  901. rb_define_method(rb_eNameError, "initialize", name_err_initialize, -1);
  902. rb_define_method(rb_eNameError, "name", name_err_name, 0);
  903. rb_define_method(rb_eNameError, "to_s", name_err_to_s, 0);
  904. rb_cNameErrorMesg = rb_define_class_under(rb_eNameError, "message", rb_cData);
  905. rb_define_singleton_method(rb_cNameErrorMesg, "!", name_err_mesg_new, 3);
  906. rb_define_method(rb_cNameErrorMesg, "==", name_err_mesg_equal, 1);
  907. rb_define_method(rb_cNameErrorMesg, "to_str", name_err_mesg_to_str, 0);
  908. rb_define_method(rb_cNameErrorMesg, "_dump", name_err_mesg_to_str, 1);
  909. rb_define_singleton_method(rb_cNameErrorMesg, "_load", name_err_mesg_load, 1);
  910. rb_eNoMethodError = rb_define_class("NoMethodError", rb_eNameError);
  911. rb_define_method(rb_eNoMethodError, "initialize", nometh_err_initialize, -1);
  912. rb_define_method(rb_eNoMethodError, "args", nometh_err_args, 0);
  913. rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError);
  914. rb_eSecurityError = rb_define_class("SecurityError", rb_eException);
  915. rb_eNoMemError = rb_define_class("NoMemoryError", rb_eException);
  916. rb_eEncodingError = rb_define_class("EncodingError", rb_eStandardError);
  917. rb_eEncCompatError = rb_define_class_under(rb_cEncoding, "CompatibilityError", rb_eEncodingError);
  918. syserr_tbl = st_init_numtable();
  919. rb_eSystemCallError = rb_define_class("SystemCallError", rb_eStandardError);
  920. rb_define_method(rb_eSystemCallError, "initialize", syserr_initialize, -1);
  921. rb_define_method(rb_eSystemCallError, "errno", syserr_errno, 0);
  922. rb_define_singleton_method(rb_eSystemCallError, "===", syserr_eqq, 1);
  923. rb_mErrno = rb_define_module("Errno");
  924. rb_define_global_function("warn", rb_warn_m, 1);
  925. }
  926. void
  927. rb_raise(VALUE exc, const char *fmt, ...)
  928. {
  929. va_list args;
  930. VALUE mesg;
  931. va_start(args, fmt);
  932. mesg = rb_vsprintf(fmt, args);
  933. va_end(args);
  934. rb_exc_raise(rb_exc_new3(exc, mesg));
  935. }
  936. void
  937. rb_loaderror(const char *fmt, ...)
  938. {
  939. va_list args;
  940. VALUE mesg;
  941. va_start(args, fmt);
  942. mesg = rb_vsprintf(fmt, args);
  943. va_end(args);
  944. rb_exc_raise(rb_exc_new3(rb_eLoadError, mesg));
  945. }
  946. void
  947. rb_notimplement(void)
  948. {
  949. rb_raise(rb_eNotImpError,
  950. "%s() function is unimplemented on this machine",
  951. rb_id2name(rb_frame_this_func()));
  952. }
  953. void
  954. rb_fatal(const char *fmt, ...)
  955. {
  956. va_list args;
  957. VALUE mesg;
  958. va_start(args, fmt);
  959. mesg = rb_vsprintf(fmt, args);
  960. va_end(args);
  961. rb_exc_fatal(rb_exc_new3(rb_eFatal, mesg));
  962. }
  963. void
  964. rb_sys_fail(const char *mesg)
  965. {
  966. int n = errno;
  967. VALUE arg;
  968. errno = 0;
  969. if (n == 0) {
  970. rb_bug("rb_sys_fail(%s) - errno == 0", mesg ? mesg : "");
  971. }
  972. arg = mesg ? rb_str_new2(mesg) : Qnil;
  973. rb_exc_raise(rb_class_new_instance(1, &arg, get_syserr(n)));
  974. }
  975. void
  976. rb_sys_warning(const char *fmt, ...)
  977. {
  978. char buf[BUFSIZ];
  979. va_list args;
  980. int errno_save;
  981. errno_save = errno;
  982. if (!RTEST(ruby_verbose)) return;
  983. snprintf(buf, BUFSIZ, "warning: %s", fmt);
  984. snprintf(buf+strlen(buf), BUFSIZ-strlen(buf), ": %s", strerror(errno_save));
  985. va_start(args, fmt);
  986. warn_print(buf, args);
  987. va_end(args);
  988. errno = errno_save;
  989. }
  990. void
  991. rb_load_fail(const char *path)
  992. {
  993. rb_loaderror("%s -- %s", strerror(errno), path);
  994. }
  995. void
  996. rb_error_frozen(const char *what)
  997. {
  998. rb_raise(rb_eRuntimeError, "can't modify frozen %s", what);
  999. }
  1000. void
  1001. rb_check_frozen(VALUE obj)
  1002. {
  1003. if (OBJ_FROZEN(obj)) rb_error_frozen(rb_obj_classname(obj));
  1004. }
  1005. void Init_syserr(void)
  1006. {
  1007. rb_eNOERROR = set_syserr(0, "NOERROR");
  1008. #include "known_errors.inc"
  1009. }
  1010. static void
  1011. err_append(const char *s)
  1012. {
  1013. rb_thread_t *th = GET_THREAD();
  1014. VALUE err = th->errinfo;
  1015. if (th->mild_compile_error) {
  1016. if (!RTEST(err)) {
  1017. err = rb_exc_new2(rb_eSyntaxError, s);
  1018. th->errinfo = err;
  1019. }
  1020. else {
  1021. VALUE str = rb_obj_as_string(err);
  1022. rb_str_cat2(str, "\n");
  1023. rb_str_cat2(str, s);
  1024. th->errinfo = rb_exc_new3(rb_eSyntaxError, str);
  1025. }
  1026. }
  1027. else {
  1028. if (!RTEST(err)) {
  1029. err = rb_exc_new2(rb_eSyntaxError, "compile error");
  1030. th->errinfo = err;
  1031. }
  1032. rb_write_error(s);
  1033. rb_write_error("\n");
  1034. }
  1035. }