PageRenderTime 68ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/benchmarks/rdoc/ruby_trunk/error.c

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