PageRenderTime 36ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 1ms

/error.c

https://github.com/wanabe/ruby
C | 3428 lines | 2175 code | 420 blank | 833 comment | 304 complexity | 24858c7f38a94191932051acdf391430 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$
  4. created at: Mon Aug 9 16:11:34 JST 1993
  5. Copyright (C) 1993-2007 Yukihiro Matsumoto
  6. **********************************************************************/
  7. #include "ruby/internal/config.h"
  8. #include <errno.h>
  9. #include <stdarg.h>
  10. #include <stdio.h>
  11. #ifdef HAVE_STDLIB_H
  12. # include <stdlib.h>
  13. #endif
  14. #ifdef HAVE_UNISTD_H
  15. # include <unistd.h>
  16. #endif
  17. #if defined __APPLE__
  18. # include <AvailabilityMacros.h>
  19. #endif
  20. #include "internal.h"
  21. #include "internal/error.h"
  22. #include "internal/eval.h"
  23. #include "internal/hash.h"
  24. #include "internal/io.h"
  25. #include "internal/load.h"
  26. #include "internal/object.h"
  27. #include "internal/symbol.h"
  28. #include "internal/thread.h"
  29. #include "internal/variable.h"
  30. #include "ruby/encoding.h"
  31. #include "ruby/st.h"
  32. #include "ruby_assert.h"
  33. #include "vm_core.h"
  34. #include "builtin.h"
  35. /*!
  36. * \addtogroup exception
  37. * \{
  38. */
  39. #ifndef EXIT_SUCCESS
  40. #define EXIT_SUCCESS 0
  41. #endif
  42. #ifndef WIFEXITED
  43. #define WIFEXITED(status) 1
  44. #endif
  45. #ifndef WEXITSTATUS
  46. #define WEXITSTATUS(status) (status)
  47. #endif
  48. VALUE rb_iseqw_local_variables(VALUE iseqval);
  49. VALUE rb_iseqw_new(const rb_iseq_t *);
  50. int rb_str_end_with_asciichar(VALUE str, int c);
  51. long rb_backtrace_length_limit = -1;
  52. VALUE rb_eEAGAIN;
  53. VALUE rb_eEWOULDBLOCK;
  54. VALUE rb_eEINPROGRESS;
  55. static VALUE rb_mWarning;
  56. static VALUE rb_cWarningBuffer;
  57. static ID id_warn;
  58. static ID id_category;
  59. static ID id_deprecated;
  60. static ID id_experimental;
  61. static VALUE sym_category;
  62. static struct {
  63. st_table *id2enum, *enum2id;
  64. } warning_categories;
  65. extern const char ruby_description[];
  66. static const char *
  67. rb_strerrno(int err)
  68. {
  69. #define defined_error(name, num) if (err == (num)) return (name);
  70. #define undefined_error(name)
  71. #include "known_errors.inc"
  72. #undef defined_error
  73. #undef undefined_error
  74. return NULL;
  75. }
  76. static int
  77. err_position_0(char *buf, long len, const char *file, int line)
  78. {
  79. if (!file) {
  80. return 0;
  81. }
  82. else if (line == 0) {
  83. return snprintf(buf, len, "%s: ", file);
  84. }
  85. else {
  86. return snprintf(buf, len, "%s:%d: ", file, line);
  87. }
  88. }
  89. RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 5, 0)
  90. static VALUE
  91. err_vcatf(VALUE str, const char *pre, const char *file, int line,
  92. const char *fmt, va_list args)
  93. {
  94. if (file) {
  95. rb_str_cat2(str, file);
  96. if (line) rb_str_catf(str, ":%d", line);
  97. rb_str_cat2(str, ": ");
  98. }
  99. if (pre) rb_str_cat2(str, pre);
  100. rb_str_vcatf(str, fmt, args);
  101. return str;
  102. }
  103. VALUE
  104. rb_syntax_error_append(VALUE exc, VALUE file, int line, int column,
  105. rb_encoding *enc, const char *fmt, va_list args)
  106. {
  107. const char *fn = NIL_P(file) ? NULL : RSTRING_PTR(file);
  108. if (!exc) {
  109. VALUE mesg = rb_enc_str_new(0, 0, enc);
  110. err_vcatf(mesg, NULL, fn, line, fmt, args);
  111. rb_str_cat2(mesg, "\n");
  112. rb_write_error_str(mesg);
  113. }
  114. else {
  115. VALUE mesg;
  116. if (NIL_P(exc)) {
  117. mesg = rb_enc_str_new(0, 0, enc);
  118. exc = rb_class_new_instance(1, &mesg, rb_eSyntaxError);
  119. }
  120. else {
  121. mesg = rb_attr_get(exc, idMesg);
  122. if (RSTRING_LEN(mesg) > 0 && *(RSTRING_END(mesg)-1) != '\n')
  123. rb_str_cat_cstr(mesg, "\n");
  124. }
  125. err_vcatf(mesg, NULL, fn, line, fmt, args);
  126. }
  127. return exc;
  128. }
  129. static unsigned int warning_disabled_categories = (
  130. 1U << RB_WARN_CATEGORY_DEPRECATED |
  131. 0);
  132. static unsigned int
  133. rb_warning_category_mask(VALUE category)
  134. {
  135. return 1U << rb_warning_category_from_name(category);
  136. }
  137. rb_warning_category_t
  138. rb_warning_category_from_name(VALUE category)
  139. {
  140. st_data_t cat_value;
  141. ID cat_id;
  142. Check_Type(category, T_SYMBOL);
  143. if (!(cat_id = rb_check_id(&category)) ||
  144. !st_lookup(warning_categories.id2enum, cat_id, &cat_value)) {
  145. rb_raise(rb_eArgError, "unknown category: %"PRIsVALUE, category);
  146. }
  147. return (rb_warning_category_t)cat_value;
  148. }
  149. static VALUE
  150. rb_warning_category_to_name(rb_warning_category_t category)
  151. {
  152. st_data_t id;
  153. if (!st_lookup(warning_categories.enum2id, category, &id)) {
  154. rb_raise(rb_eArgError, "invalid category: %d", (int)category);
  155. }
  156. return id ? ID2SYM(id) : Qnil;
  157. }
  158. void
  159. rb_warning_category_update(unsigned int mask, unsigned int bits)
  160. {
  161. warning_disabled_categories &= ~mask;
  162. warning_disabled_categories |= mask & ~bits;
  163. }
  164. MJIT_FUNC_EXPORTED bool
  165. rb_warning_category_enabled_p(rb_warning_category_t category)
  166. {
  167. return !(warning_disabled_categories & (1U << category));
  168. }
  169. /*
  170. * call-seq:
  171. * Warning[category] -> true or false
  172. *
  173. * Returns the flag to show the warning messages for +category+.
  174. * Supported categories are:
  175. *
  176. * +:deprecated+ :: deprecation warnings
  177. * * assignment of non-nil value to <code>$,</code> and <code>$;</code>
  178. * * keyword arguments
  179. * * proc/lambda without block
  180. * etc.
  181. *
  182. * +:experimental+ :: experimental features
  183. * * Pattern matching
  184. */
  185. static VALUE
  186. rb_warning_s_aref(VALUE mod, VALUE category)
  187. {
  188. rb_warning_category_t cat = rb_warning_category_from_name(category);
  189. return RBOOL(rb_warning_category_enabled_p(cat));
  190. }
  191. /*
  192. * call-seq:
  193. * Warning[category] = flag -> flag
  194. *
  195. * Sets the warning flags for +category+.
  196. * See Warning.[] for the categories.
  197. */
  198. static VALUE
  199. rb_warning_s_aset(VALUE mod, VALUE category, VALUE flag)
  200. {
  201. unsigned int mask = rb_warning_category_mask(category);
  202. unsigned int disabled = warning_disabled_categories;
  203. if (!RTEST(flag))
  204. disabled |= mask;
  205. else
  206. disabled &= ~mask;
  207. warning_disabled_categories = disabled;
  208. return flag;
  209. }
  210. /*
  211. * call-seq:
  212. * warn(msg, category: nil) -> nil
  213. *
  214. * Writes warning message +msg+ to $stderr. This method is called by
  215. * Ruby for all emitted warnings. A +category+ may be included with
  216. * the warning.
  217. *
  218. * See the documentation of the Warning module for how to customize this.
  219. */
  220. static VALUE
  221. rb_warning_s_warn(int argc, VALUE *argv, VALUE mod)
  222. {
  223. VALUE str;
  224. VALUE opt;
  225. VALUE category = Qnil;
  226. rb_scan_args(argc, argv, "1:", &str, &opt);
  227. if (!NIL_P(opt)) rb_get_kwargs(opt, &id_category, 0, 1, &category);
  228. Check_Type(str, T_STRING);
  229. rb_must_asciicompat(str);
  230. if (!NIL_P(category)) {
  231. rb_warning_category_t cat = rb_warning_category_from_name(category);
  232. if (!rb_warning_category_enabled_p(cat)) return Qnil;
  233. }
  234. rb_write_error_str(str);
  235. return Qnil;
  236. }
  237. /*
  238. * Document-module: Warning
  239. *
  240. * The Warning module contains a single method named #warn, and the
  241. * module extends itself, making Warning.warn available.
  242. * Warning.warn is called for all warnings issued by Ruby.
  243. * By default, warnings are printed to $stderr.
  244. *
  245. * Changing the behavior of Warning.warn is useful to customize how warnings are
  246. * handled by Ruby, for instance by filtering some warnings, and/or outputting
  247. * warnings somewhere other than $stderr.
  248. *
  249. * If you want to change the behavior of Warning.warn you should use
  250. * +Warning.extend(MyNewModuleWithWarnMethod)+ and you can use `super`
  251. * to get the default behavior of printing the warning to $stderr.
  252. *
  253. * Example:
  254. * module MyWarningFilter
  255. * def warn(message, category: nil, **kwargs)
  256. * if /some warning I want to ignore/.match?(message)
  257. * # ignore
  258. * else
  259. * super
  260. * end
  261. * end
  262. * end
  263. * Warning.extend MyWarningFilter
  264. *
  265. * You should never redefine Warning#warn (the instance method), as that will
  266. * then no longer provide a way to use the default behavior.
  267. *
  268. * The +warning+ gem provides convenient ways to customize Warning.warn.
  269. */
  270. static VALUE
  271. rb_warning_warn(VALUE mod, VALUE str)
  272. {
  273. return rb_funcallv(mod, id_warn, 1, &str);
  274. }
  275. static int
  276. rb_warning_warn_arity(void)
  277. {
  278. return rb_method_entry_arity(rb_method_entry(rb_singleton_class(rb_mWarning), id_warn));
  279. }
  280. static VALUE
  281. rb_warn_category(VALUE str, VALUE category)
  282. {
  283. if (RUBY_DEBUG && !NIL_P(category)) {
  284. rb_warning_category_from_name(category);
  285. }
  286. if (rb_warning_warn_arity() == 1) {
  287. return rb_warning_warn(rb_mWarning, str);
  288. }
  289. else {
  290. VALUE args[2];
  291. args[0] = str;
  292. args[1] = rb_hash_new();
  293. rb_hash_aset(args[1], sym_category, category);
  294. return rb_funcallv_kw(rb_mWarning, id_warn, 2, args, RB_PASS_KEYWORDS);
  295. }
  296. }
  297. static void
  298. rb_write_warning_str(VALUE str)
  299. {
  300. rb_warning_warn(rb_mWarning, str);
  301. }
  302. RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 4, 0)
  303. static VALUE
  304. warn_vsprintf(rb_encoding *enc, const char *file, int line, const char *fmt, va_list args)
  305. {
  306. VALUE str = rb_enc_str_new(0, 0, enc);
  307. err_vcatf(str, "warning: ", file, line, fmt, args);
  308. return rb_str_cat2(str, "\n");
  309. }
  310. void
  311. rb_compile_warn(const char *file, int line, const char *fmt, ...)
  312. {
  313. VALUE str;
  314. va_list args;
  315. if (NIL_P(ruby_verbose)) return;
  316. va_start(args, fmt);
  317. str = warn_vsprintf(NULL, file, line, fmt, args);
  318. va_end(args);
  319. rb_write_warning_str(str);
  320. }
  321. /* rb_compile_warning() reports only in verbose mode */
  322. void
  323. rb_compile_warning(const char *file, int line, const char *fmt, ...)
  324. {
  325. VALUE str;
  326. va_list args;
  327. if (!RTEST(ruby_verbose)) return;
  328. va_start(args, fmt);
  329. str = warn_vsprintf(NULL, file, line, fmt, args);
  330. va_end(args);
  331. rb_write_warning_str(str);
  332. }
  333. void
  334. rb_category_compile_warn(rb_warning_category_t category, const char *file, int line, const char *fmt, ...)
  335. {
  336. VALUE str;
  337. va_list args;
  338. if (NIL_P(ruby_verbose)) return;
  339. va_start(args, fmt);
  340. str = warn_vsprintf(NULL, file, line, fmt, args);
  341. va_end(args);
  342. rb_warn_category(str, rb_warning_category_to_name(category));
  343. }
  344. RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 0)
  345. static VALUE
  346. warning_string(rb_encoding *enc, const char *fmt, va_list args)
  347. {
  348. int line;
  349. const char *file = rb_source_location_cstr(&line);
  350. return warn_vsprintf(enc, file, line, fmt, args);
  351. }
  352. #define with_warning_string(mesg, enc, fmt) \
  353. VALUE mesg; \
  354. va_list args; va_start(args, fmt); \
  355. mesg = warning_string(enc, fmt, args); \
  356. va_end(args);
  357. void
  358. rb_warn(const char *fmt, ...)
  359. {
  360. if (!NIL_P(ruby_verbose)) {
  361. with_warning_string(mesg, 0, fmt) {
  362. rb_write_warning_str(mesg);
  363. }
  364. }
  365. }
  366. void
  367. rb_category_warn(rb_warning_category_t category, const char *fmt, ...)
  368. {
  369. if (!NIL_P(ruby_verbose)) {
  370. with_warning_string(mesg, 0, fmt) {
  371. rb_warn_category(mesg, rb_warning_category_to_name(category));
  372. }
  373. }
  374. }
  375. void
  376. rb_enc_warn(rb_encoding *enc, const char *fmt, ...)
  377. {
  378. if (!NIL_P(ruby_verbose)) {
  379. with_warning_string(mesg, enc, fmt) {
  380. rb_write_warning_str(mesg);
  381. }
  382. }
  383. }
  384. /* rb_warning() reports only in verbose mode */
  385. void
  386. rb_warning(const char *fmt, ...)
  387. {
  388. if (RTEST(ruby_verbose)) {
  389. with_warning_string(mesg, 0, fmt) {
  390. rb_write_warning_str(mesg);
  391. }
  392. }
  393. }
  394. /* rb_category_warning() reports only in verbose mode */
  395. void
  396. rb_category_warning(rb_warning_category_t category, const char *fmt, ...)
  397. {
  398. if (RTEST(ruby_verbose)) {
  399. with_warning_string(mesg, 0, fmt) {
  400. rb_warn_category(mesg, rb_warning_category_to_name(category));
  401. }
  402. }
  403. }
  404. VALUE
  405. rb_warning_string(const char *fmt, ...)
  406. {
  407. with_warning_string(mesg, 0, fmt) {
  408. }
  409. return mesg;
  410. }
  411. #if 0
  412. void
  413. rb_enc_warning(rb_encoding *enc, const char *fmt, ...)
  414. {
  415. if (RTEST(ruby_verbose)) {
  416. with_warning_string(mesg, enc, fmt) {
  417. rb_write_warning_str(mesg);
  418. }
  419. }
  420. }
  421. #endif
  422. static bool
  423. deprecation_warning_enabled(void)
  424. {
  425. if (NIL_P(ruby_verbose)) return false;
  426. if (!rb_warning_category_enabled_p(RB_WARN_CATEGORY_DEPRECATED)) return false;
  427. return true;
  428. }
  429. static void
  430. warn_deprecated(VALUE mesg, const char *removal, const char *suggest)
  431. {
  432. rb_str_set_len(mesg, RSTRING_LEN(mesg) - 1);
  433. rb_str_cat_cstr(mesg, " is deprecated");
  434. if (removal) {
  435. rb_str_catf(mesg, " and will be removed in Ruby %s", removal);
  436. }
  437. if (suggest) rb_str_catf(mesg, "; use %s instead", suggest);
  438. rb_str_cat_cstr(mesg, "\n");
  439. rb_warn_category(mesg, ID2SYM(id_deprecated));
  440. }
  441. void
  442. rb_warn_deprecated(const char *fmt, const char *suggest, ...)
  443. {
  444. if (!deprecation_warning_enabled()) return;
  445. va_list args;
  446. va_start(args, suggest);
  447. VALUE mesg = warning_string(0, fmt, args);
  448. va_end(args);
  449. warn_deprecated(mesg, NULL, suggest);
  450. }
  451. void
  452. rb_warn_deprecated_to_remove(const char *removal, const char *fmt, const char *suggest, ...)
  453. {
  454. if (!deprecation_warning_enabled()) return;
  455. va_list args;
  456. va_start(args, suggest);
  457. VALUE mesg = warning_string(0, fmt, args);
  458. va_end(args);
  459. warn_deprecated(mesg, removal, suggest);
  460. }
  461. static inline int
  462. end_with_asciichar(VALUE str, int c)
  463. {
  464. return RB_TYPE_P(str, T_STRING) &&
  465. rb_str_end_with_asciichar(str, c);
  466. }
  467. /* :nodoc: */
  468. static VALUE
  469. warning_write(int argc, VALUE *argv, VALUE buf)
  470. {
  471. while (argc-- > 0) {
  472. rb_str_append(buf, *argv++);
  473. }
  474. return buf;
  475. }
  476. VALUE rb_ec_backtrace_location_ary(const rb_execution_context_t *ec, long lev, long n, bool skip_internal);
  477. static VALUE
  478. rb_warn_m(rb_execution_context_t *ec, VALUE exc, VALUE msgs, VALUE uplevel, VALUE category)
  479. {
  480. VALUE location = Qnil;
  481. int argc = RARRAY_LENINT(msgs);
  482. const VALUE *argv = RARRAY_CONST_PTR(msgs);
  483. if (!NIL_P(ruby_verbose) && argc > 0) {
  484. VALUE str = argv[0];
  485. if (!NIL_P(uplevel)) {
  486. long lev = NUM2LONG(uplevel);
  487. if (lev < 0) {
  488. rb_raise(rb_eArgError, "negative level (%ld)", lev);
  489. }
  490. location = rb_ec_backtrace_location_ary(ec, lev + 1, 1, TRUE);
  491. if (!NIL_P(location)) {
  492. location = rb_ary_entry(location, 0);
  493. }
  494. }
  495. if (argc > 1 || !NIL_P(uplevel) || !end_with_asciichar(str, '\n')) {
  496. VALUE path;
  497. if (NIL_P(uplevel)) {
  498. str = rb_str_tmp_new(0);
  499. }
  500. else if (NIL_P(location) ||
  501. NIL_P(path = rb_funcall(location, rb_intern("path"), 0))) {
  502. str = rb_str_new_cstr("warning: ");
  503. }
  504. else {
  505. str = rb_sprintf("%s:%ld: warning: ",
  506. rb_string_value_ptr(&path),
  507. NUM2LONG(rb_funcall(location, rb_intern("lineno"), 0)));
  508. }
  509. RBASIC_SET_CLASS(str, rb_cWarningBuffer);
  510. rb_io_puts(argc, argv, str);
  511. RBASIC_SET_CLASS(str, rb_cString);
  512. }
  513. if (!NIL_P(category)) {
  514. category = rb_to_symbol_type(category);
  515. rb_warning_category_from_name(category);
  516. }
  517. if (exc == rb_mWarning) {
  518. rb_must_asciicompat(str);
  519. rb_write_error_str(str);
  520. }
  521. else {
  522. rb_warn_category(str, category);
  523. }
  524. }
  525. return Qnil;
  526. }
  527. #define MAX_BUG_REPORTERS 0x100
  528. static struct bug_reporters {
  529. void (*func)(FILE *out, void *data);
  530. void *data;
  531. } bug_reporters[MAX_BUG_REPORTERS];
  532. static int bug_reporters_size;
  533. int
  534. rb_bug_reporter_add(void (*func)(FILE *, void *), void *data)
  535. {
  536. struct bug_reporters *reporter;
  537. if (bug_reporters_size >= MAX_BUG_REPORTERS) {
  538. return 0; /* failed to register */
  539. }
  540. reporter = &bug_reporters[bug_reporters_size++];
  541. reporter->func = func;
  542. reporter->data = data;
  543. return 1;
  544. }
  545. /* SIGSEGV handler might have a very small stack. Thus we need to use it carefully. */
  546. #define REPORT_BUG_BUFSIZ 256
  547. static FILE *
  548. bug_report_file(const char *file, int line)
  549. {
  550. char buf[REPORT_BUG_BUFSIZ];
  551. FILE *out = stderr;
  552. int len = err_position_0(buf, sizeof(buf), file, line);
  553. if ((ssize_t)fwrite(buf, 1, len, out) == (ssize_t)len ||
  554. (ssize_t)fwrite(buf, 1, len, (out = stdout)) == (ssize_t)len) {
  555. return out;
  556. }
  557. return NULL;
  558. }
  559. FUNC_MINIMIZED(static void bug_important_message(FILE *out, const char *const msg, size_t len));
  560. static void
  561. bug_important_message(FILE *out, const char *const msg, size_t len)
  562. {
  563. const char *const endmsg = msg + len;
  564. const char *p = msg;
  565. if (!len) return;
  566. if (isatty(fileno(out))) {
  567. static const char red[] = "\033[;31;1;7m";
  568. static const char green[] = "\033[;32;7m";
  569. static const char reset[] = "\033[m";
  570. const char *e = strchr(p, '\n');
  571. const int w = (int)(e - p);
  572. do {
  573. int i = (int)(e - p);
  574. fputs(*p == ' ' ? green : red, out);
  575. fwrite(p, 1, e - p, out);
  576. for (; i < w; ++i) fputc(' ', out);
  577. fputs(reset, out);
  578. fputc('\n', out);
  579. } while ((p = e + 1) < endmsg && (e = strchr(p, '\n')) != 0 && e > p + 1);
  580. }
  581. fwrite(p, 1, endmsg - p, out);
  582. }
  583. static void
  584. preface_dump(FILE *out)
  585. {
  586. #if defined __APPLE__
  587. static const char msg[] = ""
  588. "-- Crash Report log information "
  589. "--------------------------------------------\n"
  590. " See Crash Report log file in one of the following locations:\n"
  591. # if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
  592. " * ~/Library/Logs/CrashReporter\n"
  593. " * /Library/Logs/CrashReporter\n"
  594. # endif
  595. " * ~/Library/Logs/DiagnosticReports\n"
  596. " * /Library/Logs/DiagnosticReports\n"
  597. " for more details.\n"
  598. "Don't forget to include the above Crash Report log file in bug reports.\n"
  599. "\n";
  600. const size_t msglen = sizeof(msg) - 1;
  601. #else
  602. const char *msg = NULL;
  603. const size_t msglen = 0;
  604. #endif
  605. bug_important_message(out, msg, msglen);
  606. }
  607. static void
  608. postscript_dump(FILE *out)
  609. {
  610. #if defined __APPLE__
  611. static const char msg[] = ""
  612. "[IMPORTANT]"
  613. /*" ------------------------------------------------"*/
  614. "\n""Don't forget to include the Crash Report log file under\n"
  615. # if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
  616. "CrashReporter or "
  617. # endif
  618. "DiagnosticReports directory in bug reports.\n"
  619. /*"------------------------------------------------------------\n"*/
  620. "\n";
  621. const size_t msglen = sizeof(msg) - 1;
  622. #else
  623. const char *msg = NULL;
  624. const size_t msglen = 0;
  625. #endif
  626. bug_important_message(out, msg, msglen);
  627. }
  628. RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 0)
  629. static void
  630. bug_report_begin_valist(FILE *out, const char *fmt, va_list args)
  631. {
  632. char buf[REPORT_BUG_BUFSIZ];
  633. fputs("[BUG] ", out);
  634. vsnprintf(buf, sizeof(buf), fmt, args);
  635. fputs(buf, out);
  636. snprintf(buf, sizeof(buf), "\n%s\n\n", ruby_description);
  637. fputs(buf, out);
  638. preface_dump(out);
  639. }
  640. #define bug_report_begin(out, fmt) do { \
  641. va_list args; \
  642. va_start(args, fmt); \
  643. bug_report_begin_valist(out, fmt, args); \
  644. va_end(args); \
  645. } while (0)
  646. static void
  647. bug_report_end(FILE *out)
  648. {
  649. /* call additional bug reporters */
  650. {
  651. int i;
  652. for (i=0; i<bug_reporters_size; i++) {
  653. struct bug_reporters *reporter = &bug_reporters[i];
  654. (*reporter->func)(out, reporter->data);
  655. }
  656. }
  657. postscript_dump(out);
  658. }
  659. #define report_bug(file, line, fmt, ctx) do { \
  660. FILE *out = bug_report_file(file, line); \
  661. if (out) { \
  662. bug_report_begin(out, fmt); \
  663. rb_vm_bugreport(ctx); \
  664. bug_report_end(out); \
  665. } \
  666. } while (0) \
  667. #define report_bug_valist(file, line, fmt, ctx, args) do { \
  668. FILE *out = bug_report_file(file, line); \
  669. if (out) { \
  670. bug_report_begin_valist(out, fmt, args); \
  671. rb_vm_bugreport(ctx); \
  672. bug_report_end(out); \
  673. } \
  674. } while (0) \
  675. NORETURN(static void die(void));
  676. static void
  677. die(void)
  678. {
  679. #if defined(_WIN32) && defined(RUBY_MSVCRT_VERSION) && RUBY_MSVCRT_VERSION >= 80
  680. _set_abort_behavior( 0, _CALL_REPORTFAULT);
  681. #endif
  682. abort();
  683. }
  684. RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 0)
  685. void
  686. rb_bug_without_die(const char *fmt, va_list args)
  687. {
  688. const char *file = NULL;
  689. int line = 0;
  690. if (GET_EC()) {
  691. file = rb_source_location_cstr(&line);
  692. }
  693. report_bug_valist(file, line, fmt, NULL, args);
  694. }
  695. void
  696. rb_bug(const char *fmt, ...)
  697. {
  698. va_list args;
  699. va_start(args, fmt);
  700. rb_bug_without_die(fmt, args);
  701. va_end(args);
  702. die();
  703. }
  704. void
  705. rb_bug_for_fatal_signal(ruby_sighandler_t default_sighandler, int sig, const void *ctx, const char *fmt, ...)
  706. {
  707. const char *file = NULL;
  708. int line = 0;
  709. if (GET_EC()) {
  710. file = rb_source_location_cstr(&line);
  711. }
  712. report_bug(file, line, fmt, ctx);
  713. if (default_sighandler) default_sighandler(sig);
  714. die();
  715. }
  716. void
  717. rb_bug_errno(const char *mesg, int errno_arg)
  718. {
  719. if (errno_arg == 0)
  720. rb_bug("%s: errno == 0 (NOERROR)", mesg);
  721. else {
  722. const char *errno_str = rb_strerrno(errno_arg);
  723. if (errno_str)
  724. rb_bug("%s: %s (%s)", mesg, strerror(errno_arg), errno_str);
  725. else
  726. rb_bug("%s: %s (%d)", mesg, strerror(errno_arg), errno_arg);
  727. }
  728. }
  729. /*
  730. * this is safe to call inside signal handler and timer thread
  731. * (which isn't a Ruby Thread object)
  732. */
  733. #define write_or_abort(fd, str, len) (write((fd), (str), (len)) < 0 ? abort() : (void)0)
  734. #define WRITE_CONST(fd,str) write_or_abort((fd),(str),sizeof(str) - 1)
  735. void
  736. rb_async_bug_errno(const char *mesg, int errno_arg)
  737. {
  738. WRITE_CONST(2, "[ASYNC BUG] ");
  739. write_or_abort(2, mesg, strlen(mesg));
  740. WRITE_CONST(2, "\n");
  741. if (errno_arg == 0) {
  742. WRITE_CONST(2, "errno == 0 (NOERROR)\n");
  743. }
  744. else {
  745. const char *errno_str = rb_strerrno(errno_arg);
  746. if (!errno_str)
  747. errno_str = "undefined errno";
  748. write_or_abort(2, errno_str, strlen(errno_str));
  749. }
  750. WRITE_CONST(2, "\n\n");
  751. write_or_abort(2, ruby_description, strlen(ruby_description));
  752. abort();
  753. }
  754. void
  755. rb_report_bug_valist(VALUE file, int line, const char *fmt, va_list args)
  756. {
  757. report_bug_valist(RSTRING_PTR(file), line, fmt, NULL, args);
  758. }
  759. MJIT_FUNC_EXPORTED void
  760. rb_assert_failure(const char *file, int line, const char *name, const char *expr)
  761. {
  762. FILE *out = stderr;
  763. fprintf(out, "Assertion Failed: %s:%d:", file, line);
  764. if (name) fprintf(out, "%s:", name);
  765. fprintf(out, "%s\n%s\n\n", expr, ruby_description);
  766. preface_dump(out);
  767. rb_vm_bugreport(NULL);
  768. bug_report_end(out);
  769. die();
  770. }
  771. static const char builtin_types[][10] = {
  772. "", /* 0x00, */
  773. "Object",
  774. "Class",
  775. "Module",
  776. "Float",
  777. "String",
  778. "Regexp",
  779. "Array",
  780. "Hash",
  781. "Struct",
  782. "Integer",
  783. "File",
  784. "Data", /* internal use: wrapped C pointers */
  785. "MatchData", /* data of $~ */
  786. "Complex",
  787. "Rational",
  788. "", /* 0x10 */
  789. "nil",
  790. "true",
  791. "false",
  792. "Symbol", /* :symbol */
  793. "Integer",
  794. "undef", /* internal use: #undef; should not happen */
  795. "", /* 0x17 */
  796. "", /* 0x18 */
  797. "", /* 0x19 */
  798. "<Memo>", /* internal use: general memo */
  799. "<Node>", /* internal use: syntax tree node */
  800. "<iClass>", /* internal use: mixed-in module holder */
  801. };
  802. const char *
  803. rb_builtin_type_name(int t)
  804. {
  805. const char *name;
  806. if ((unsigned int)t >= numberof(builtin_types)) return 0;
  807. name = builtin_types[t];
  808. if (*name) return name;
  809. return 0;
  810. }
  811. static VALUE
  812. displaying_class_of(VALUE x)
  813. {
  814. switch (x) {
  815. case Qfalse: return rb_fstring_cstr("false");
  816. case Qnil: return rb_fstring_cstr("nil");
  817. case Qtrue: return rb_fstring_cstr("true");
  818. default: return rb_obj_class(x);
  819. }
  820. }
  821. static const char *
  822. builtin_class_name(VALUE x)
  823. {
  824. const char *etype;
  825. if (NIL_P(x)) {
  826. etype = "nil";
  827. }
  828. else if (FIXNUM_P(x)) {
  829. etype = "Integer";
  830. }
  831. else if (SYMBOL_P(x)) {
  832. etype = "Symbol";
  833. }
  834. else if (RB_TYPE_P(x, T_TRUE)) {
  835. etype = "true";
  836. }
  837. else if (RB_TYPE_P(x, T_FALSE)) {
  838. etype = "false";
  839. }
  840. else {
  841. etype = NULL;
  842. }
  843. return etype;
  844. }
  845. const char *
  846. rb_builtin_class_name(VALUE x)
  847. {
  848. const char *etype = builtin_class_name(x);
  849. if (!etype) {
  850. etype = rb_obj_classname(x);
  851. }
  852. return etype;
  853. }
  854. COLDFUNC NORETURN(static void unexpected_type(VALUE, int, int));
  855. #define UNDEF_LEAKED "undef leaked to the Ruby space"
  856. static void
  857. unexpected_type(VALUE x, int xt, int t)
  858. {
  859. const char *tname = rb_builtin_type_name(t);
  860. VALUE mesg, exc = rb_eFatal;
  861. if (tname) {
  862. mesg = rb_sprintf("wrong argument type %"PRIsVALUE" (expected %s)",
  863. displaying_class_of(x), tname);
  864. exc = rb_eTypeError;
  865. }
  866. else if (xt > T_MASK && xt <= 0x3f) {
  867. mesg = rb_sprintf("unknown type 0x%x (0x%x given, probably comes"
  868. " from extension library for ruby 1.8)", t, xt);
  869. }
  870. else {
  871. mesg = rb_sprintf("unknown type 0x%x (0x%x given)", t, xt);
  872. }
  873. rb_exc_raise(rb_exc_new_str(exc, mesg));
  874. }
  875. void
  876. rb_check_type(VALUE x, int t)
  877. {
  878. int xt;
  879. if (RB_UNLIKELY(x == Qundef)) {
  880. rb_bug(UNDEF_LEAKED);
  881. }
  882. xt = TYPE(x);
  883. if (xt != t || (xt == T_DATA && rbimpl_rtypeddata_p(x))) {
  884. /*
  885. * Typed data is not simple `T_DATA`, but in a sense an
  886. * extension of `struct RVALUE`, which are incompatible with
  887. * each other except when inherited.
  888. *
  889. * So it is not enough to just check `T_DATA`, it must be
  890. * identified by its `type` using `Check_TypedStruct` instead.
  891. */
  892. unexpected_type(x, xt, t);
  893. }
  894. }
  895. void
  896. rb_unexpected_type(VALUE x, int t)
  897. {
  898. if (RB_UNLIKELY(x == Qundef)) {
  899. rb_bug(UNDEF_LEAKED);
  900. }
  901. unexpected_type(x, TYPE(x), t);
  902. }
  903. int
  904. rb_typeddata_inherited_p(const rb_data_type_t *child, const rb_data_type_t *parent)
  905. {
  906. while (child) {
  907. if (child == parent) return 1;
  908. child = child->parent;
  909. }
  910. return 0;
  911. }
  912. int
  913. rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
  914. {
  915. if (!RB_TYPE_P(obj, T_DATA) ||
  916. !RTYPEDDATA_P(obj) || !rb_typeddata_inherited_p(RTYPEDDATA_TYPE(obj), data_type)) {
  917. return 0;
  918. }
  919. return 1;
  920. }
  921. #undef rb_typeddata_is_instance_of
  922. int
  923. rb_typeddata_is_instance_of(VALUE obj, const rb_data_type_t *data_type)
  924. {
  925. return rb_typeddata_is_instance_of_inline(obj, data_type);
  926. }
  927. void *
  928. rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
  929. {
  930. VALUE actual;
  931. if (!RB_TYPE_P(obj, T_DATA)) {
  932. actual = displaying_class_of(obj);
  933. }
  934. else if (!RTYPEDDATA_P(obj)) {
  935. actual = displaying_class_of(obj);
  936. }
  937. else if (!rb_typeddata_inherited_p(RTYPEDDATA_TYPE(obj), data_type)) {
  938. const char *name = RTYPEDDATA_TYPE(obj)->wrap_struct_name;
  939. actual = rb_str_new_cstr(name); /* or rb_fstring_cstr? not sure... */
  940. }
  941. else {
  942. return DATA_PTR(obj);
  943. }
  944. const char *expected = data_type->wrap_struct_name;
  945. rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected %s)",
  946. actual, expected);
  947. UNREACHABLE_RETURN(NULL);
  948. }
  949. /* exception classes */
  950. VALUE rb_eException;
  951. VALUE rb_eSystemExit;
  952. VALUE rb_eInterrupt;
  953. VALUE rb_eSignal;
  954. VALUE rb_eFatal;
  955. VALUE rb_eStandardError;
  956. VALUE rb_eRuntimeError;
  957. VALUE rb_eFrozenError;
  958. VALUE rb_eTypeError;
  959. VALUE rb_eArgError;
  960. VALUE rb_eIndexError;
  961. VALUE rb_eKeyError;
  962. VALUE rb_eRangeError;
  963. VALUE rb_eNameError;
  964. VALUE rb_eEncodingError;
  965. VALUE rb_eEncCompatError;
  966. VALUE rb_eNoMethodError;
  967. VALUE rb_eSecurityError;
  968. VALUE rb_eNotImpError;
  969. VALUE rb_eNoMemError;
  970. VALUE rb_cNameErrorMesg;
  971. VALUE rb_eNoMatchingPatternError;
  972. VALUE rb_eNoMatchingPatternKeyError;
  973. VALUE rb_eScriptError;
  974. VALUE rb_eSyntaxError;
  975. VALUE rb_eLoadError;
  976. VALUE rb_eSystemCallError;
  977. VALUE rb_mErrno;
  978. static VALUE rb_eNOERROR;
  979. ID ruby_static_id_cause;
  980. #define id_cause ruby_static_id_cause
  981. static ID id_message, id_backtrace;
  982. static ID id_key, id_matchee, id_args, id_Errno, id_errno, id_i_path;
  983. static ID id_receiver, id_recv, id_iseq, id_local_variables;
  984. static ID id_private_call_p, id_top, id_bottom;
  985. #define id_bt idBt
  986. #define id_bt_locations idBt_locations
  987. #define id_mesg idMesg
  988. #define id_name idName
  989. #undef rb_exc_new_cstr
  990. VALUE
  991. rb_exc_new(VALUE etype, const char *ptr, long len)
  992. {
  993. VALUE mesg = rb_str_new(ptr, len);
  994. return rb_class_new_instance(1, &mesg, etype);
  995. }
  996. VALUE
  997. rb_exc_new_cstr(VALUE etype, const char *s)
  998. {
  999. return rb_exc_new(etype, s, strlen(s));
  1000. }
  1001. VALUE
  1002. rb_exc_new_str(VALUE etype, VALUE str)
  1003. {
  1004. StringValue(str);
  1005. return rb_class_new_instance(1, &str, etype);
  1006. }
  1007. static VALUE
  1008. exc_init(VALUE exc, VALUE mesg)
  1009. {
  1010. rb_ivar_set(exc, id_mesg, mesg);
  1011. rb_ivar_set(exc, id_bt, Qnil);
  1012. return exc;
  1013. }
  1014. /*
  1015. * call-seq:
  1016. * Exception.new(msg = nil) -> exception
  1017. * Exception.exception(msg = nil) -> exception
  1018. *
  1019. * Construct a new Exception object, optionally passing in
  1020. * a message.
  1021. */
  1022. static VALUE
  1023. exc_initialize(int argc, VALUE *argv, VALUE exc)
  1024. {
  1025. VALUE arg;
  1026. arg = (!rb_check_arity(argc, 0, 1) ? Qnil : argv[0]);
  1027. return exc_init(exc, arg);
  1028. }
  1029. /*
  1030. * Document-method: exception
  1031. *
  1032. * call-seq:
  1033. * exc.exception([string]) -> an_exception or exc
  1034. *
  1035. * With no argument, or if the argument is the same as the receiver,
  1036. * return the receiver. Otherwise, create a new
  1037. * exception object of the same class as the receiver, but with a
  1038. * message equal to <code>string.to_str</code>.
  1039. *
  1040. */
  1041. static VALUE
  1042. exc_exception(int argc, VALUE *argv, VALUE self)
  1043. {
  1044. VALUE exc;
  1045. argc = rb_check_arity(argc, 0, 1);
  1046. if (argc == 0) return self;
  1047. if (argc == 1 && self == argv[0]) return self;
  1048. exc = rb_obj_clone(self);
  1049. rb_ivar_set(exc, id_mesg, argv[0]);
  1050. return exc;
  1051. }
  1052. /*
  1053. * call-seq:
  1054. * exception.to_s -> string
  1055. *
  1056. * Returns exception's message (or the name of the exception if
  1057. * no message is set).
  1058. */
  1059. static VALUE
  1060. exc_to_s(VALUE exc)
  1061. {
  1062. VALUE mesg = rb_attr_get(exc, idMesg);
  1063. if (NIL_P(mesg)) return rb_class_name(CLASS_OF(exc));
  1064. return rb_String(mesg);
  1065. }
  1066. /* FIXME: Include eval_error.c */
  1067. void rb_error_write(VALUE errinfo, VALUE emesg, VALUE errat, VALUE str, VALUE highlight, VALUE reverse);
  1068. VALUE
  1069. rb_get_message(VALUE exc)
  1070. {
  1071. VALUE e = rb_check_funcall(exc, id_message, 0, 0);
  1072. if (e == Qundef) return Qnil;
  1073. if (!RB_TYPE_P(e, T_STRING)) e = rb_check_string_type(e);
  1074. return e;
  1075. }
  1076. /*
  1077. * call-seq:
  1078. * Exception.to_tty? -> true or false
  1079. *
  1080. * Returns +true+ if exception messages will be sent to a tty.
  1081. */
  1082. static VALUE
  1083. exc_s_to_tty_p(VALUE self)
  1084. {
  1085. return RBOOL(rb_stderr_tty_p());
  1086. }
  1087. /*
  1088. * call-seq:
  1089. * exception.full_message(highlight: bool, order: [:top or :bottom]) -> string
  1090. *
  1091. * Returns formatted string of _exception_.
  1092. * The returned string is formatted using the same format that Ruby uses
  1093. * when printing an uncaught exceptions to stderr.
  1094. *
  1095. * If _highlight_ is +true+ the default error handler will send the
  1096. * messages to a tty.
  1097. *
  1098. * _order_ must be either of +:top+ or +:bottom+, and places the error
  1099. * message and the innermost backtrace come at the top or the bottom.
  1100. *
  1101. * The default values of these options depend on <code>$stderr</code>
  1102. * and its +tty?+ at the timing of a call.
  1103. */
  1104. static VALUE
  1105. exc_full_message(int argc, VALUE *argv, VALUE exc)
  1106. {
  1107. VALUE opt, str, emesg, errat;
  1108. enum {kw_highlight, kw_order, kw_max_};
  1109. static ID kw[kw_max_];
  1110. VALUE args[kw_max_] = {Qnil, Qnil};
  1111. rb_scan_args(argc, argv, "0:", &opt);
  1112. if (!NIL_P(opt)) {
  1113. if (!kw[0]) {
  1114. #define INIT_KW(n) kw[kw_##n] = rb_intern_const(#n)
  1115. INIT_KW(highlight);
  1116. INIT_KW(order);
  1117. #undef INIT_KW
  1118. }
  1119. rb_get_kwargs(opt, kw, 0, kw_max_, args);
  1120. switch (args[kw_highlight]) {
  1121. default:
  1122. rb_bool_expected(args[kw_highlight], "highlight");
  1123. UNREACHABLE;
  1124. case Qundef: args[kw_highlight] = Qnil; break;
  1125. case Qtrue: case Qfalse: case Qnil: break;
  1126. }
  1127. if (args[kw_order] == Qundef) {
  1128. args[kw_order] = Qnil;
  1129. }
  1130. else {
  1131. ID id = rb_check_id(&args[kw_order]);
  1132. if (id == id_bottom) args[kw_order] = Qtrue;
  1133. else if (id == id_top) args[kw_order] = Qfalse;
  1134. else {
  1135. rb_raise(rb_eArgError, "expected :top or :bottom as "
  1136. "order: %+"PRIsVALUE, args[kw_order]);
  1137. }
  1138. }
  1139. }
  1140. str = rb_str_new2("");
  1141. errat = rb_get_backtrace(exc);
  1142. emesg = rb_get_message(exc);
  1143. rb_error_write(exc, emesg, errat, str, args[kw_highlight], args[kw_order]);
  1144. return str;
  1145. }
  1146. /*
  1147. * call-seq:
  1148. * exception.message -> string
  1149. *
  1150. * Returns the result of invoking <code>exception.to_s</code>.
  1151. * Normally this returns the exception's message or name.
  1152. */
  1153. static VALUE
  1154. exc_message(VALUE exc)
  1155. {
  1156. return rb_funcallv(exc, idTo_s, 0, 0);
  1157. }
  1158. /*
  1159. * call-seq:
  1160. * exception.inspect -> string
  1161. *
  1162. * Return this exception's class name and message.
  1163. */
  1164. static VALUE
  1165. exc_inspect(VALUE exc)
  1166. {
  1167. VALUE str, klass;
  1168. klass = CLASS_OF(exc);
  1169. exc = rb_obj_as_string(exc);
  1170. if (RSTRING_LEN(exc) == 0) {
  1171. return rb_class_name(klass);
  1172. }
  1173. str = rb_str_buf_new2("#<");
  1174. klass = rb_class_name(klass);
  1175. rb_str_buf_append(str, klass);
  1176. rb_str_buf_cat(str, ": ", 2);
  1177. rb_str_buf_append(str, exc);
  1178. rb_str_buf_cat(str, ">", 1);
  1179. return str;
  1180. }
  1181. /*
  1182. * call-seq:
  1183. * exception.backtrace -> array or nil
  1184. *
  1185. * Returns any backtrace associated with the exception. The backtrace
  1186. * is an array of strings, each containing either ``filename:lineNo: in
  1187. * `method''' or ``filename:lineNo.''
  1188. *
  1189. * def a
  1190. * raise "boom"
  1191. * end
  1192. *
  1193. * def b
  1194. * a()
  1195. * end
  1196. *
  1197. * begin
  1198. * b()
  1199. * rescue => detail
  1200. * print detail.backtrace.join("\n")
  1201. * end
  1202. *
  1203. * <em>produces:</em>
  1204. *
  1205. * prog.rb:2:in `a'
  1206. * prog.rb:6:in `b'
  1207. * prog.rb:10
  1208. *
  1209. * In the case no backtrace has been set, +nil+ is returned
  1210. *
  1211. * ex = StandardError.new
  1212. * ex.backtrace
  1213. * #=> nil
  1214. */
  1215. static VALUE
  1216. exc_backtrace(VALUE exc)
  1217. {
  1218. VALUE obj;
  1219. obj = rb_attr_get(exc, id_bt);
  1220. if (rb_backtrace_p(obj)) {
  1221. obj = rb_backtrace_to_str_ary(obj);
  1222. /* rb_ivar_set(exc, id_bt, obj); */
  1223. }
  1224. return obj;
  1225. }
  1226. static VALUE rb_check_backtrace(VALUE);
  1227. VALUE
  1228. rb_get_backtrace(VALUE exc)
  1229. {
  1230. ID mid = id_backtrace;
  1231. VALUE info;
  1232. if (rb_method_basic_definition_p(CLASS_OF(exc), id_backtrace)) {
  1233. VALUE klass = rb_eException;
  1234. rb_execution_context_t *ec = GET_EC();
  1235. if (NIL_P(exc))
  1236. return Qnil;
  1237. EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_CALL, exc, mid, mid, klass, Qundef);
  1238. info = exc_backtrace(exc);
  1239. EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_RETURN, exc, mid, mid, klass, info);
  1240. }
  1241. else {
  1242. info = rb_funcallv(exc, mid, 0, 0);
  1243. }
  1244. if (NIL_P(info)) return Qnil;
  1245. return rb_check_backtrace(info);
  1246. }
  1247. /*
  1248. * call-seq:
  1249. * exception.backtrace_locations -> array or nil
  1250. *
  1251. * Returns any backtrace associated with the exception. This method is
  1252. * similar to Exception#backtrace, but the backtrace is an array of
  1253. * Thread::Backtrace::Location.
  1254. *
  1255. * This method is not affected by Exception#set_backtrace().
  1256. */
  1257. static VALUE
  1258. exc_backtrace_locations(VALUE exc)
  1259. {
  1260. VALUE obj;
  1261. obj = rb_attr_get(exc, id_bt_locations);
  1262. if (!NIL_P(obj)) {
  1263. obj = rb_backtrace_to_location_ary(obj);
  1264. }
  1265. return obj;
  1266. }
  1267. static VALUE
  1268. rb_check_backtrace(VALUE bt)
  1269. {
  1270. long i;
  1271. static const char err[] = "backtrace must be Array of String";
  1272. if (!NIL_P(bt)) {
  1273. if (RB_TYPE_P(bt, T_STRING)) return rb_ary_new3(1, bt);
  1274. if (rb_backtrace_p(bt)) return bt;
  1275. if (!RB_TYPE_P(bt, T_ARRAY)) {
  1276. rb_raise(rb_eTypeError, err);
  1277. }
  1278. for (i=0;i<RARRAY_LEN(bt);i++) {
  1279. VALUE e = RARRAY_AREF(bt, i);
  1280. if (!RB_TYPE_P(e, T_STRING)) {
  1281. rb_raise(rb_eTypeError, err);
  1282. }
  1283. }
  1284. }
  1285. return bt;
  1286. }
  1287. /*
  1288. * call-seq:
  1289. * exc.set_backtrace(backtrace) -> array
  1290. *
  1291. * Sets the backtrace information associated with +exc+. The +backtrace+ must
  1292. * be an array of String objects or a single String in the format described
  1293. * in Exception#backtrace.
  1294. *
  1295. */
  1296. static VALUE
  1297. exc_set_backtrace(VALUE exc, VALUE bt)
  1298. {
  1299. return rb_ivar_set(exc, id_bt, rb_check_backtrace(bt));
  1300. }
  1301. MJIT_FUNC_EXPORTED VALUE
  1302. rb_exc_set_backtrace(VALUE exc, VALUE bt)
  1303. {
  1304. return exc_set_backtrace(exc, bt);
  1305. }
  1306. /*
  1307. * call-seq:
  1308. * exception.cause -> an_exception or nil
  1309. *
  1310. * Returns the previous exception ($!) at the time this exception was raised.
  1311. * This is useful for wrapping exceptions and retaining the original exception
  1312. * information.
  1313. */
  1314. static VALUE
  1315. exc_cause(VALUE exc)
  1316. {
  1317. return rb_attr_get(exc, id_cause);
  1318. }
  1319. static VALUE
  1320. try_convert_to_exception(VALUE obj)
  1321. {
  1322. return rb_check_funcall(obj, idException, 0, 0);
  1323. }
  1324. /*
  1325. * call-seq:
  1326. * exc == obj -> true or false
  1327. *
  1328. * Equality---If <i>obj</i> is not an Exception, returns
  1329. * <code>false</code>. Otherwise, returns <code>true</code> if <i>exc</i> and
  1330. * <i>obj</i> share same class, messages, and backtrace.
  1331. */
  1332. static VALUE
  1333. exc_equal(VALUE exc, VALUE obj)
  1334. {
  1335. VALUE mesg, backtrace;
  1336. if (exc == obj) return Qtrue;
  1337. if (rb_obj_class(exc) != rb_obj_class(obj)) {
  1338. int state;
  1339. obj = rb_protect(try_convert_to_exception, obj, &state);
  1340. if (state || obj == Qundef) {
  1341. rb_set_errinfo(Qnil);
  1342. return Qfalse;
  1343. }
  1344. if (rb_obj_class(exc) != rb_obj_class(obj)) return Qfalse;
  1345. mesg = rb_check_funcall(obj, id_message, 0, 0);
  1346. if (mesg == Qundef) return Qfalse;
  1347. backtrace = rb_check_funcall(obj, id_backtrace, 0, 0);
  1348. if (backtrace == Qundef) return Qfalse;
  1349. }
  1350. else {
  1351. mesg = rb_attr_get(obj, id_mesg);
  1352. backtrace = exc_backtrace(obj);
  1353. }
  1354. if (!rb_equal(rb_attr_get(exc, id_mesg), mesg))
  1355. return Qfalse;
  1356. return rb_equal(exc_backtrace(exc), backtrace);
  1357. }
  1358. /*
  1359. * call-seq:
  1360. * SystemExit.new -> system_exit
  1361. * SystemExit.new(status) -> system_exit
  1362. * SystemExit.new(status, msg) -> system_exit
  1363. * SystemExit.new(msg) -> system_exit
  1364. *
  1365. * Create a new +SystemExit+ exception with the given status and message.
  1366. * Status is true, false, or an integer.
  1367. * If status is not given, true is used.
  1368. */
  1369. static VALUE
  1370. exit_initialize(int argc, VALUE *argv, VALUE exc)
  1371. {
  1372. VALUE status;
  1373. if (argc > 0) {
  1374. status = *argv;
  1375. switch (status) {
  1376. case Qtrue:
  1377. status = INT2FIX(EXIT_SUCCESS);
  1378. ++argv;
  1379. --argc;
  1380. break;
  1381. case Qfalse:
  1382. status = INT2FIX(EXIT_FAILURE);
  1383. ++argv;
  1384. --argc;
  1385. break;
  1386. default:
  1387. status = rb_check_to_int(status);
  1388. if (NIL_P(status)) {
  1389. status = INT2FIX(EXIT_SUCCESS);
  1390. }
  1391. else {
  1392. #if EXIT_SUCCESS != 0
  1393. if (status == INT2FIX(0))
  1394. status = INT2FIX(EXIT_SUCCESS);
  1395. #endif
  1396. ++argv;
  1397. --argc;
  1398. }
  1399. break;
  1400. }
  1401. }
  1402. else {
  1403. status = INT2FIX(EXIT_SUCCESS);
  1404. }
  1405. rb_call_super(argc, argv);
  1406. rb_ivar_set(exc, id_status, status);
  1407. return exc;
  1408. }
  1409. /*
  1410. * call-seq:
  1411. * system_exit.status -> integer
  1412. *
  1413. * Return the status value associated with this system exit.
  1414. */
  1415. static VALUE
  1416. exit_status(VALUE exc)
  1417. {
  1418. return rb_attr_get(exc, id_status);
  1419. }
  1420. /*
  1421. * call-seq:
  1422. * system_exit.success? -> true or false
  1423. *
  1424. * Returns +true+ if exiting successful, +false+ if not.
  1425. */
  1426. static VALUE
  1427. exit_success_p(VALUE exc)
  1428. {
  1429. VALUE status_val = rb_attr_get(exc, id_status);
  1430. int status;
  1431. if (NIL_P(status_val))
  1432. return Qtrue;
  1433. status = NUM2INT(status_val);
  1434. return RBOOL(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
  1435. }
  1436. static VALUE
  1437. err_init_recv(VALUE exc, VALUE recv)
  1438. {
  1439. if (recv != Qundef) rb_ivar_set(exc, id_recv, recv);
  1440. return exc;
  1441. }
  1442. /*
  1443. * call-seq:
  1444. * FrozenError.new(msg=nil, receiver: nil) -> frozen_error
  1445. *
  1446. * Construct a new FrozenError exception. If given the <i>receiver</i>
  1447. * parameter may subsequently be examined using the FrozenError#receiver
  1448. * method.
  1449. *
  1450. * a = [].freeze
  1451. * raise FrozenError.new("can't modify frozen array", receiver: a)
  1452. */
  1453. static VALUE
  1454. frozen_err_initialize(int argc, VALUE *argv, VALUE self)
  1455. {
  1456. ID keywords[1];
  1457. VALUE values[numberof(keywords)], options;
  1458. argc = rb_scan_args(argc, argv, "*:", NULL, &options);
  1459. keywords[0] = id_receiver;
  1460. rb_get_kwargs(options, keywords, 0, numberof(values), values);
  1461. rb_call_super(argc, argv);
  1462. err_init_recv(self, values[0]);
  1463. return self;
  1464. }
  1465. /*
  1466. * Document-method: FrozenError#receiver
  1467. * call-seq:
  1468. * frozen_error.receiver -> object
  1469. *
  1470. * Return the receiver associated with this FrozenError exception.
  1471. */
  1472. #define frozen_err_receiver name_err_receiver
  1473. void
  1474. rb_name_error(ID id, const char *fmt, ...)
  1475. {
  1476. VALUE exc, argv[2];
  1477. va_list args;
  1478. va_start(args, fmt);
  1479. argv[0] = rb_vsprintf(fmt, args);
  1480. va_end(args);
  1481. argv[1] = ID2SYM(id);
  1482. exc = rb_class_new_instance(2, argv, rb_eNameError);
  1483. rb_exc_raise(exc);
  1484. }
  1485. void
  1486. rb_name_error_str(VALUE str, const char *fmt, ...)
  1487. {
  1488. VALUE exc, argv[2];
  1489. va_list args;
  1490. va_start(args, fmt);
  1491. argv[0] = rb_vsprintf(fmt, args);
  1492. va_end(args);
  1493. argv[1] = str;
  1494. exc = rb_class_new_instance(2, argv, rb_eNameError);
  1495. rb_exc_raise(exc);
  1496. }
  1497. static VALUE
  1498. name_err_init_attr(VALUE exc, VALUE recv, VALUE method)
  1499. {
  1500. const rb_execution_context_t *ec = GET_EC();
  1501. rb_control_frame_t *cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp);
  1502. cfp = rb_vm_get_ruby_level_next_cfp(ec, cfp);
  1503. rb_ivar_set(exc, id_name, method);
  1504. err_init_recv(exc, recv);
  1505. if (cfp) rb_ivar_set(exc, id_iseq, rb_iseqw_new(cfp->iseq));
  1506. return exc;
  1507. }
  1508. /*
  1509. * call-seq:
  1510. * NameError.new(msg=nil, name=nil, receiver: nil) -> name_error
  1511. *
  1512. * Construct a new NameError exception. If given the <i>name</i>
  1513. * parameter may subsequently be examined using the NameError#name
  1514. * method. <i>receiver</i> parameter allows to pass object in
  1515. * context of which the error happened. Example:
  1516. *
  1517. * [1, 2, 3].method(:rject) # NameError with name "rject" and receiver: Array
  1518. * [1, 2, 3].singleton_method(:rject) # NameError with name "rject" and receiver: [1, 2, 3]
  1519. */
  1520. static VALUE
  1521. name_err_initialize(int argc, VALUE *argv, VALUE self)
  1522. {
  1523. ID keywords[1];
  1524. VALUE values[numberof(keywords)], name, options;
  1525. argc = rb_scan_args(argc, argv, "*:", NULL, &options);
  1526. keywords[0] = id_receiver;
  1527. rb_get_kwargs(options, keywords, 0, numberof(values), values);
  1528. name = (argc > 1) ? argv[--argc] : Qnil;
  1529. rb_call_super(argc, argv);
  1530. name_err_init_attr(self, values[0], name);
  1531. return self;
  1532. }
  1533. static VALUE rb_name_err_mesg_new(VALUE mesg, VALUE recv, VALUE method);
  1534. static VALUE
  1535. name_err_init(VALUE exc, VALUE mesg, VALUE recv, VALUE method)
  1536. {
  1537. exc_init(exc, rb_name_err_mesg_new(mesg, recv, method));
  1538. return name_err_init_attr(exc, recv, method);
  1539. }
  1540. VALUE
  1541. rb_name_err_new(VALUE mesg, VALUE recv, VALUE method)
  1542. {
  1543. VALUE exc = rb_obj_alloc(rb_eNameError);
  1544. return name_err_init(exc, mesg, recv, method);
  1545. }
  1546. /*
  1547. * call-seq:
  1548. * name_error.name -> string or nil
  1549. *
  1550. * Return the name associated with this NameError exception.
  1551. */
  1552. static VALUE
  1553. name_err_name(VALUE self)
  1554. {
  1555. return rb_attr_get(self, id_name);
  1556. }
  1557. /*
  1558. * call-seq:
  1559. * name_error.local_variables -> array
  1560. *
  1561. * Return a list of the local variable names defined where this
  1562. * NameError exception was raised.
  1563. *
  1564. * Internal use only.
  1565. */
  1566. static VALUE
  1567. name_err_local_variables(VALUE self)
  1568. {
  1569. VALUE vars = rb_attr_get(self, id_local_variables);
  1570. if (NIL_P(vars)) {
  1571. VALUE iseqw = rb_attr_get(self, id_iseq);
  1572. if (!NIL_P(iseqw)) vars = rb_iseqw_local_variables(iseqw);
  1573. if (NIL_P(vars)) vars = rb_ary_new();
  1574. rb_ivar_set(self, id_local_variables, vars);
  1575. }
  1576. return vars;
  1577. }
  1578. static VALUE
  1579. nometh_err_init_attr(VALUE exc, VALUE args, int priv)
  1580. {
  1581. rb_ivar_set(exc, id_args, args);
  1582. rb_ivar_set(exc, id_private_call_p, RBOOL(priv));
  1583. return exc;
  1584. }
  1585. /*
  1586. * call-seq:
  1587. * NoMethodError.new(msg=nil, name=nil, args=nil, private=false, receiver: nil) -> no_method_error
  1588. *
  1589. * Construct a NoMethodError exception for a method of the given name
  1590. * called with the given arguments. The name may be accessed using
  1591. * the <code>#name</code> method on the resulting object, and the
  1592. * arguments using the <code>#args</code> method.
  1593. *
  1594. * If <i>private</i> argument were passed, it designates method was
  1595. * attempted to call in private context, and can be accessed with
  1596. * <code>#private_call?</code> method.
  1597. *
  1598. * <i>receiver</i> argument stores an object whose method was called.
  1599. */
  1600. static VALUE
  1601. nometh_err_initialize(int argc, VALUE *argv, VALUE self)
  1602. {
  1603. int priv;
  1604. VALUE args, options;
  1605. argc = rb_scan_args(argc, argv, "*:", NULL, &options);
  1606. priv = (argc > 3) && (--argc, RTEST(argv[argc]));
  1607. args = (argc > 2) ? argv[--argc] : Qnil;
  1608. if (!NIL_P(options)) argv[argc++] = options;
  1609. rb_call_super_kw(argc, argv, RB_PASS_CALLED_KEYWORDS);
  1610. return nometh_err_init_attr(self, args, priv);
  1611. }
  1612. VALUE
  1613. rb_nomethod_err_new(VALUE mesg, VALUE recv, VALUE method, VALUE args, int priv)
  1614. {
  1615. VALUE exc = rb_obj_alloc(rb_eNoMethodError);
  1616. name_err_init(exc, mesg, recv, method);
  1617. return nometh_err_init_attr(exc, args, priv);
  1618. }
  1619. /* :nodoc: */
  1620. enum {
  1621. NAME_ERR_MESG__MESG,
  1622. NAME_ERR_MESG__RECV,
  1623. NAME_ERR_MESG__NAME,
  1624. NAME_ERR_MESG_COUNT
  1625. };
  1626. static void
  1627. name_err_mesg_mark(void *p)
  1628. {
  1629. VALUE *ptr = p;
  1630. rb_gc_mark_locations(ptr, ptr+NAME_ERR_MESG_COUNT);
  1631. }
  1632. #define name_err_mesg_free RUBY_TYPED_DEFAULT_FREE
  1633. static size_t
  1634. name_err_mesg_memsize(const void *p)
  1635. {
  1636. return NAME_ERR_MESG_COUNT * sizeof(VALUE);
  1637. }
  1638. static const rb_data_type_t name_err_mesg_data_type = {
  1639. "name_err_mesg",
  1640. {
  1641. name_err_mesg_mark,
  1642. name_err_mesg_free,
  1643. name_err_mesg_memsize,
  1644. },
  1645. 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
  1646. };
  1647. /* :nodoc: */
  1648. static VALUE
  1649. rb_name_err_mesg_init(VALUE klass, VALUE mesg, VALUE recv, VALUE method)
  1650. {
  1651. VALUE result = TypedData_Wrap_Struct(klass, &name_err_mesg_data_type, 0);
  1652. VALUE *ptr = ALLOC_N(VALUE, NAME_ERR_MESG_COUNT);
  1653. ptr[NAME_ERR_MESG__MESG] = mesg;
  1654. ptr[NAME_ERR_MESG__RECV] = recv;
  1655. ptr[NAME_ERR_MESG__NAME] = method;
  1656. RTYPEDDATA_DATA(result) = ptr;
  1657. return result;
  1658. }
  1659. /* :nodoc: */
  1660. static VALUE
  1661. rb_name_err_mesg_new(VALUE mesg, VALUE recv, VALUE method)
  1662. {
  1663. return rb_name_err_mesg_init(rb_cNameErrorMesg, mesg, recv, method);
  1664. }
  1665. /* :nodoc: */
  1666. static VALUE
  1667. name_err_mesg_alloc(VALUE klass)
  1668. {
  1669. return rb_name_err_mesg_init(klass, Qnil, Qnil, Qnil);
  1670. }
  1671. /* :nodoc: */
  1672. static VALUE
  1673. name_err_mesg_init_copy(VALUE obj1, VALUE obj2)
  1674. {
  1675. VALUE *ptr1, *ptr2;
  1676. if (obj1 == obj2) return obj1;
  1677. rb_obj_init_copy(obj1, obj2);
  1678. TypedData_Get_Struct(obj1, VALUE, &name_err_mesg_data_type, ptr1);
  1679. TypedData_Get_Struct(obj2, VALUE, &name_err_mesg_data_type, ptr2);
  1680. MEMCPY(ptr1, ptr2, VALUE, NAME_ERR_MESG_COUNT);
  1681. return obj1;
  1682. }
  1683. /* :nodoc: */
  1684. static VALUE
  1685. name_err_mesg_equal(VALUE obj1, VALUE obj2)
  1686. {
  1687. VALUE *ptr1, *ptr2;
  1688. int i;
  1689. if (obj1 == obj2) return Qtrue;
  1690. if (rb_obj_class(obj2) != rb_cNameErrorMesg)
  1691. return Qfalse;
  1692. TypedData_Get_Struct(obj1, VALUE, &name_err_mesg_data_type, ptr1);
  1693. TypedData_Get_Struct(obj2, VALUE, &name_err_mesg_data_type, ptr2);
  1694. for (i=0; i<NAME_ERR_MESG_COUNT; i++) {
  1695. if (!rb_equal(ptr1[i], ptr2[i]))
  1696. return Qfalse;
  1697. }
  1698. return Qtrue;
  1699. }
  1700. /* :nodoc: */
  1701. static VALUE
  1702. name_err_mesg_receiver_name(VALUE obj)
  1703. {
  1704. if (RB_SPECIAL_CONST_P(obj)) return Qundef;
  1705. if (RB_BUILTIN_TYPE(obj) == T_MODULE || RB_BUILTIN_TYPE(obj) == T_CLASS) {
  1706. return rb_check_funcall(obj, rb_intern("name"), 0, 0);
  1707. }
  1708. return Qundef;
  1709. }
  1710. /* :nodoc: */
  1711. static VALUE
  1712. name_err_mesg_to_str(VALUE obj)
  1713. {
  1714. VALUE *ptr, mesg;
  1715. TypedData_Get_Struct(obj, VALUE, &name_err_mesg_data_type, ptr);
  1716. mesg = ptr[NAME_ERR_MESG__MESG];
  1717. if (NIL_P(mesg)) return Qnil;
  1718. else {
  1719. struct RString s_str, d_str;
  1720. VALUE c, s, d = 0, args[4];
  1721. int state = 0, singleton = 0;
  1722. rb_encoding *usascii = rb_usascii_encoding();
  1723. #define FAKE_CSTR(v, str) rb_setup_fake_str((v), (str), rb_strlen_lit(str), usascii)
  1724. obj = ptr[NAME_ERR_MESG__RECV];
  1725. switch (obj) {
  1726. case Qnil:
  1727. d = FAKE_CSTR(&d_str, "nil");
  1728. break;
  1729. case Qtrue:
  1730. d = FAKE_CSTR(&d_str, "true");
  1731. break;
  1732. case Qfalse:
  1733. d = FAKE_CSTR(&d_str, "false");
  1734. break;
  1735. default:
  1736. d = rb_protect(name_err_mesg_receiver_name, obj, &state);
  1737. if (state || d == Qundef || d == Qnil)
  1738. d = rb_protect(rb_inspect, obj, &state);
  1739. if (state) {
  1740. rb_set_errinfo(Qnil);
  1741. }
  1742. d = rb_check_string_type(d);
  1743. if (NIL_P(d)) {
  1744. d = rb_any_to_s(obj);
  1745. }
  1746. singleton = (RSTRING_LEN(d) > 0 && RSTRING_PTR(d)[0] == '#');
  1747. break;
  1748. }
  1749. if (!singleton) {
  1750. s = FAKE_CSTR(&s_str, ":");
  1751. c = rb_class_name(CLASS_OF(obj));
  1752. }
  1753. else {
  1754. c = s = FAKE_CSTR(&s_str, "");
  1755. }
  1756. args[0] = rb_obj_as_string(ptr[NAME_ERR_MESG__NAME]);
  1757. args[1] = d;
  1758. args[2] = s;
  1759. args[3] = c;
  1760. mesg = rb_str_format(4, args, mesg);
  1761. }
  1762. return mesg;
  1763. }
  1764. /* :nodoc: */
  1765. static VALUE
  1766. name_err_mesg_dump(VALUE obj, VALUE limit)
  1767. {
  1768. return name_err_mesg_to_str(obj);
  1769. }
  1770. /* :nodoc: */
  1771. static VALUE
  1772. name_err_mesg_load(VALUE klass, VALUE str)
  1773. {
  1774. return str;
  1775. }
  1776. /*
  1777. * call-seq:
  1778. * name_error.receiver -> object
  1779. *
  1780. * Return the receiver associated with this NameError exception.
  1781. */
  1782. static VALUE
  1783. name_err_receiver(VALUE self)
  1784. {
  1785. VALUE *ptr, recv, mesg;
  1786. recv = rb_ivar_lookup(self, id_recv, Qundef);
  1787. if (recv != Qundef) return recv;
  1788. mesg = rb_attr_get(self, id_mesg);
  1789. if (!rb_typeddata_is_kind_of(mesg, &name_err_mesg_data_type)) {
  1790. rb_raise(rb_eArgError, "no receiver is available");
  1791. }
  1792. ptr = DATA_PTR(mesg);
  1793. return ptr[NAME_ERR_MESG__RECV];
  1794. }
  1795. /*
  1796. * call-seq:
  1797. * no_method_error.args -> obj
  1798. *
  1799. * Return the arguments passed in as the third parameter to
  1800. * the constructor.
  1801. */
  1802. static VALUE
  1803. nometh_err_args(VALUE self)
  1804. {
  1805. return rb_attr_get(self, id_args);
  1806. }
  1807. /*
  1808. * call-seq:
  1809. * no_method_error.private_call? -> true or false
  1810. *
  1811. * Return true if the caused method was called as private.
  1812. */
  1813. static VALUE
  1814. nometh_err_private_call_p(VALUE self)
  1815. {
  1816. return rb_attr_get(self, id_private_call_p);
  1817. }
  1818. void
  1819. rb_invalid_str(const char *str, const char *type)
  1820. {
  1821. VALUE s = rb_str_new2(str);
  1822. rb_raise(rb_eArgError, "invalid value for %s: %+"PRIsVALUE, type, s);
  1823. }
  1824. /*
  1825. * call-seq:
  1826. * key_error.receiver -> object
  1827. *
  1828. * Return the receiver associated with this KeyError exception.
  1829. */
  1830. static VALUE
  1831. key_err_receiver(VALUE self)
  1832. {
  1833. VALUE recv;
  1834. recv = rb_ivar_lookup(self, id_receiver, Qundef);
  1835. if (recv != Qundef) return recv;
  1836. rb_raise(rb_eArgError, "no receiver is available");
  1837. }
  1838. /*
  1839. * call-seq:
  1840. * key_error.key -> object
  1841. *
  1842. * Return the key caused this KeyError exception.
  1843. */
  1844. static VALUE
  1845. key_err_key(VALUE self)
  1846. {
  1847. VALUE key;
  1848. key = rb_ivar_lookup(self, id_key, Qundef);
  1849. if (key != Qundef) return key;
  1850. rb_raise(rb_eArgError, "no key is available");
  1851. }
  1852. VALUE
  1853. rb_key_err_new(VALUE mesg, VALUE recv, VALUE key)
  1854. {
  1855. VALUE exc = rb_obj_alloc(rb_eKeyError);
  1856. rb_ivar_set(exc, id_mesg, mesg);
  1857. rb_ivar_set(exc, id_bt, Qnil);
  1858. rb_ivar_set(exc, id_key, key);
  1859. rb_ivar_set(exc, id_receiver, recv);
  1860. return exc;
  1861. }
  1862. /*
  1863. * call-seq:
  1864. * KeyError.new(message=nil, receiver: nil, key: nil) -> key_error
  1865. *
  1866. * Construct a new +KeyError+ exception with the given message,
  1867. * receiver and key.
  1868. */
  1869. static VALUE
  1870. key_err_initialize(int argc, VALUE *argv, VALUE self)
  1871. {
  1872. VALUE options;
  1873. rb_call_super(rb_scan_args(argc, argv, "01:", NULL, &options), argv);
  1874. if (!NIL_P(options)) {
  1875. ID keywords[2];
  1876. VALUE values[numberof(keywords)];
  1877. int i;
  1878. keywords[0] = id_receiver;
  1879. keywords[1] = id_key;
  1880. rb_get_kwargs(options, keywords, 0, numberof(values), values);
  1881. for (i = 0; i < numberof(values); ++i) {
  1882. if (values[i] != Qundef) {
  1883. rb_ivar_set(self, keywords[i], values[i]);
  1884. }
  1885. }
  1886. }
  1887. return self;
  1888. }
  1889. /*
  1890. * call-seq:
  1891. * no_matching_pattern_key_error.matchee -> object
  1892. *
  1893. * Return the matchee associated with this NoMatchingPatternKeyError exception.
  1894. */
  1895. static VALUE
  1896. no_matching_pattern_key_err_matchee(VALUE self)
  1897. {
  1898. VALUE matchee;
  1899. matchee = rb_ivar_lookup(self, id_matchee, Qundef);
  1900. if (matchee != Qundef) return matchee;
  1901. rb_raise(rb_eArgError, "no matchee is available");
  1902. }
  1903. /*
  1904. * call-seq:
  1905. * no_matching_pattern_key_error.key -> object
  1906. *
  1907. * Return the key caused this NoMatchingPatternKeyError exception.
  1908. */
  1909. static VALUE
  1910. no_matching_pattern_key_err_key(VALUE self)
  1911. {
  1912. VALUE key;
  1913. key = rb_ivar_lookup(self, id_key, Qundef);
  1914. if (key != Qundef) return key;
  1915. rb_raise(rb_eArgError, "no key is available");
  1916. }
  1917. /*
  1918. * call-seq:
  1919. * NoMatchingPatternKeyError.new(message=nil, matchee: nil, key: nil) -> no_matching_pattern_key_error
  1920. *
  1921. * Construct a new +NoMatchingPatternKeyError+ exception with the given message,
  1922. * matchee and key.
  1923. */
  1924. static VALUE
  1925. no_matching_pattern_key_err_initialize(int argc, VALUE *argv, VALUE self)
  1926. {
  1927. VALUE options;
  1928. rb_call_super(rb_scan_args(argc, argv, "01:", NULL, &options), argv);
  1929. if (!NIL_P(options)) {
  1930. ID keywords[2];
  1931. VALUE values[numberof(keywords)];
  1932. int i;
  1933. keywords[0] = id_matchee;
  1934. keywords[1] = id_key;
  1935. rb_get_kwargs(options, keywords, 0, numberof(values), values);
  1936. for (i = 0; i < numberof(values); ++i) {
  1937. if (values[i] != Qundef) {
  1938. rb_ivar_set(self, keywords[i], values[i]);
  1939. }
  1940. }
  1941. }
  1942. return self;
  1943. }
  1944. /*
  1945. * call-seq:
  1946. * SyntaxError.new([msg]) -> syntax_error
  1947. *
  1948. * Construct a SyntaxError exception.
  1949. */
  1950. static VALUE
  1951. syntax_error_initialize(int argc, VALUE *argv, VALUE self)
  1952. {
  1953. VALUE mesg;
  1954. if (argc == 0) {
  1955. mesg = rb_fstring_lit("compile error");
  1956. argc = 1;
  1957. argv = &mesg;
  1958. }
  1959. return rb_call_super(argc, argv);
  1960. }
  1961. /*
  1962. * Document-module: Errno
  1963. *
  1964. * Ruby exception objects are subclasses of Exception. However,
  1965. * operating systems typically report errors using plain
  1966. * integers. Module Errno is created dynamically to map these
  1967. * operating system errors to Ruby classes, with each error number
  1968. * generating its own subclass of SystemCallError. As the subclass
  1969. * is created in module Errno, its name will start
  1970. * <code>Errno::</code>.
  1971. *
  1972. * The names of the <code>Errno::</code> classes depend on the
  1973. * environment in which Ruby runs. On a typical Unix or Windows
  1974. * platform, there are Errno classes such as Errno::EACCES,
  1975. * Errno::EAGAIN, Errno::EINTR, and so on.
  1976. *
  1977. * The integer operating system error number corresponding to a
  1978. * particular error is available as the class constant
  1979. * <code>Errno::</code><em>error</em><code>::Errno</code>.
  1980. *
  1981. * Errno::EACCES::Errno #=> 13
  1982. * Errno::EAGAIN::Errno #=> 11
  1983. * Errno::EINTR::Errno #=> 4
  1984. *
  1985. * The full list of operating system errors on your particular platform
  1986. * are available as the constants of Errno.
  1987. *
  1988. * Errno.constants #=> :E2BIG, :EACCES, :EADDRINUSE, :EADDRNOTAVAIL, ...
  1989. */
  1990. static st_table *syserr_tbl;
  1991. static VALUE
  1992. set_syserr(int n, const char *name)
  1993. {
  1994. st_data_t error;
  1995. if (!st_lookup(syserr_tbl, n, &error)) {
  1996. error = rb_define_class_under(rb_mErrno, name, rb_eSystemCallError);
  1997. /* capture nonblock errnos for WaitReadable/WaitWritable subclasses */
  1998. switch (n) {
  1999. case EAGAIN:
  2000. rb_eEAGAIN = error;
  2001. #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
  2002. break;
  2003. case EWOULDBLOCK:
  2004. #endif
  2005. rb_eEWOULDBLOCK = error;
  2006. break;
  2007. case EINPROGRESS:
  2008. rb_eEINPROGRESS = error;
  2009. break;
  2010. }
  2011. rb_define_const(error, "Errno", INT2NUM(n));
  2012. st_add_direct(syserr_tbl, n, error);
  2013. }
  2014. else {
  2015. rb_define_const(rb_mErrno, name, error);
  2016. }
  2017. return error;
  2018. }
  2019. static VALUE
  2020. get_syserr(int n)
  2021. {
  2022. st_data_t error;
  2023. if (!st_lookup(syserr_tbl, n, &error)) {
  2024. char name[8]; /* some Windows' errno have 5 digits. */
  2025. snprintf(name, sizeof(name), "E%03d", n);
  2026. error = set_syserr(n, name);
  2027. }
  2028. return error;
  2029. }
  2030. /*
  2031. * call-seq:
  2032. * SystemCallError.new(msg, errno) -> system_call_error_subclass
  2033. *
  2034. * If _errno_ corresponds to a known system error code, constructs the
  2035. * appropriate Errno class for that error, otherwise constructs a
  2036. * generic SystemCallError object. The error number is subsequently
  2037. * available via the #errno method.
  2038. */
  2039. static VALUE
  2040. syserr_initialize(int argc, VALUE *argv, VALUE self)
  2041. {
  2042. #if !defined(_WIN32)
  2043. char *strerror();
  2044. #endif
  2045. const char *err;
  2046. VALUE mesg, error, func, errmsg;
  2047. VALUE klass = rb_obj_class(self);
  2048. if (klass == rb_eSystemCallError) {
  2049. st_data_t data = (st_data_t)klass;
  2050. rb_scan_args(argc, argv, "12", &mesg, &error, &func);
  2051. if (argc == 1 && FIXNUM_P(mesg)) {
  2052. error = mesg; mesg = Qnil;
  2053. }
  2054. if (!NIL_P(error) && st_lookup(syserr_tbl, NUM2LONG(error), &data)) {
  2055. klass = (VALUE)data;
  2056. /* change class */
  2057. if (!RB_TYPE_P(self, T_OBJECT)) { /* insurance to avoid type crash */
  2058. rb_raise(rb_eTypeError, "invalid instance type");
  2059. }
  2060. RBASIC_SET_CLASS(self, klass);
  2061. }
  2062. }
  2063. else {
  2064. rb_scan_args(argc, argv, "02", &mesg, &func);
  2065. error = rb_const_get(klass, id_Errno);
  2066. }
  2067. if (!NIL_P(error)) err = strerror(NUM2INT(error));
  2068. else err = "unknown error";
  2069. errmsg = rb_enc_str_new_cstr(err, rb_locale_encoding());
  2070. if (!NIL_P(mesg)) {
  2071. VALUE str = StringValue(mesg);
  2072. if (!NIL_P(func)) rb_str_catf(errmsg, " @ %"PRIsVALUE, func);
  2073. rb_str_catf(errmsg, " - %"PRIsVALUE, str);
  2074. }
  2075. mesg = errmsg;
  2076. rb_call_super(1, &mesg);
  2077. rb_ivar_set(self, id_errno, error);
  2078. return self;
  2079. }
  2080. /*
  2081. * call-seq:
  2082. * system_call_error.errno -> integer
  2083. *
  2084. * Return this SystemCallError's error number.
  2085. */
  2086. static VALUE
  2087. syserr_errno(VALUE self)
  2088. {
  2089. return rb_attr_get(self, id_errno);
  2090. }
  2091. /*
  2092. * call-seq:
  2093. * system_call_error === other -> true or false
  2094. *
  2095. * Return +true+ if the receiver is a generic +SystemCallError+, or
  2096. * if the error numbers +self+ and _other_ are the same.
  2097. */
  2098. static VALUE
  2099. syserr_eqq(VALUE self, VALUE exc)
  2100. {
  2101. VALUE num, e;
  2102. if (!rb_obj_is_kind_of(exc, rb_eSystemCallError)) {
  2103. if (!rb_respond_to(exc, id_errno)) return Qfalse;
  2104. }
  2105. else if (self == rb_eSystemCallError) return Qtrue;
  2106. num = rb_attr_get(exc, id_errno);
  2107. if (NIL_P(num)) {
  2108. num = rb_funcallv(exc, id_errno, 0, 0);
  2109. }
  2110. e = rb_const_get(self, id_Errno);
  2111. if (FIXNUM_P(num) ? num == e : rb_equal(num, e))
  2112. return Qtrue;
  2113. return Qfalse;
  2114. }
  2115. /*
  2116. * Document-class: StandardError
  2117. *
  2118. * The most standard error types are subclasses of StandardError. A
  2119. * rescue clause without an explicit Exception class will rescue all
  2120. * StandardErrors (and only those).
  2121. *
  2122. * def foo
  2123. * raise "Oups"
  2124. * end
  2125. * foo rescue "Hello" #=> "Hello"
  2126. *
  2127. * On the other hand:
  2128. *
  2129. * require 'does/not/exist' rescue "Hi"
  2130. *
  2131. * <em>raises the exception:</em>
  2132. *
  2133. * LoadError: no such file to load -- does/not/exist
  2134. *
  2135. */
  2136. /*
  2137. * Document-class: SystemExit
  2138. *
  2139. * Raised by +exit+ to initiate the termination of the script.
  2140. */
  2141. /*
  2142. * Document-class: SignalException
  2143. *
  2144. * Raised when a signal is received.
  2145. *
  2146. * begin
  2147. * Process.kill('HUP',Process.pid)
  2148. * sleep # wait for receiver to handle signal sent by Process.kill
  2149. * rescue SignalException => e
  2150. * puts "received Exception #{e}"
  2151. * end
  2152. *
  2153. * <em>produces:</em>
  2154. *
  2155. * received Exception SIGHUP
  2156. */
  2157. /*
  2158. * Document-class: Interrupt
  2159. *
  2160. * Raised when the interrupt signal is received, typically because the
  2161. * user has pressed Control-C (on most posix platforms). As such, it is a
  2162. * subclass of +SignalException+.
  2163. *
  2164. * begin
  2165. * puts "Press ctrl-C when you get bored"
  2166. * loop {}
  2167. * rescue Interrupt => e
  2168. * puts "Note: You will typically use Signal.trap instead."
  2169. * end
  2170. *
  2171. * <em>produces:</em>
  2172. *
  2173. * Press ctrl-C when you get bored
  2174. *
  2175. * <em>then waits until it is interrupted with Control-C and then prints:</em>
  2176. *
  2177. * Note: You will typically use Signal.trap instead.
  2178. */
  2179. /*
  2180. * Document-class: TypeError
  2181. *
  2182. * Raised when encountering an object that is not of the expected type.
  2183. *
  2184. * [1, 2, 3].first("two")
  2185. *
  2186. * <em>raises the exception:</em>
  2187. *
  2188. * TypeError: no implicit conversion of String into Integer
  2189. *
  2190. */
  2191. /*
  2192. * Document-class: ArgumentError
  2193. *
  2194. * Raised when the arguments are wrong and there isn't a more specific
  2195. * Exception class.
  2196. *
  2197. * Ex: passing the wrong number of arguments
  2198. *
  2199. * [1, 2, 3].first(4, 5)
  2200. *
  2201. * <em>raises the exception:</em>
  2202. *
  2203. * ArgumentError: wrong number of arguments (given 2, expected 1)
  2204. *
  2205. * Ex: passing an argument that is not acceptable:
  2206. *
  2207. * [1, 2, 3].first(-4)
  2208. *
  2209. * <em>raises the exception:</em>
  2210. *
  2211. * ArgumentError: negative array size
  2212. */
  2213. /*
  2214. * Document-class: IndexError
  2215. *
  2216. * Raised when the given index is invalid.
  2217. *
  2218. * a = [:foo, :bar]
  2219. * a.fetch(0) #=> :foo
  2220. * a[4] #=> nil
  2221. * a.fetch(4) #=> IndexError: index 4 outside of array bounds: -2...2
  2222. *
  2223. */
  2224. /*
  2225. * Document-class: KeyError
  2226. *
  2227. * Raised when the specified key is not found. It is a subclass of
  2228. * IndexError.
  2229. *
  2230. * h = {"foo" => :bar}
  2231. * h.fetch("foo") #=> :bar
  2232. * h.fetch("baz") #=> KeyError: key not found: "baz"
  2233. *
  2234. */
  2235. /*
  2236. * Document-class: RangeError
  2237. *
  2238. * Raised when a given numerical value is out of range.
  2239. *
  2240. * [1, 2, 3].drop(1 << 100)
  2241. *
  2242. * <em>raises the exception:</em>
  2243. *
  2244. * RangeError: bignum too big to convert into `long'
  2245. */
  2246. /*
  2247. * Document-class: ScriptError
  2248. *
  2249. * ScriptError is the superclass for errors raised when a script
  2250. * can not be executed because of a +LoadError+,
  2251. * +NotImplementedError+ or a +SyntaxError+. Note these type of
  2252. * +ScriptErrors+ are not +StandardError+ and will not be
  2253. * rescued unless it is specified explicitly (or its ancestor
  2254. * +Exception+).
  2255. */
  2256. /*
  2257. * Document-class: SyntaxError
  2258. *
  2259. * Raised when encountering Ruby code with an invalid syntax.
  2260. *
  2261. * eval("1+1=2")
  2262. *
  2263. * <em>raises the exception:</em>
  2264. *
  2265. * SyntaxError: (eval):1: syntax error, unexpected '=', expecting $end
  2266. */
  2267. /*
  2268. * Document-class: LoadError
  2269. *
  2270. * Raised when a file required (a Ruby script, extension library, ...)
  2271. * fails to load.
  2272. *
  2273. * require 'this/file/does/not/exist'
  2274. *
  2275. * <em>raises the exception:</em>
  2276. *
  2277. * LoadError: no such file to load -- this/file/does/not/exist
  2278. */
  2279. /*
  2280. * Document-class: NotImplementedError
  2281. *
  2282. * Raised when a feature is not implemented on the current platform. For
  2283. * example, methods depending on the +fsync+ or +fork+ system calls may
  2284. * raise this exception if the underlying operating system or Ruby
  2285. * runtime does not support them.
  2286. *
  2287. * Note that if +fork+ raises a +NotImplementedError+, then
  2288. * <code>respond_to?(:fork)</code> returns +false+.
  2289. */
  2290. /*
  2291. * Document-class: NameError
  2292. *
  2293. * Raised when a given name is invalid or undefined.
  2294. *
  2295. * puts foo
  2296. *
  2297. * <em>raises the exception:</em>
  2298. *
  2299. * NameError: undefined local variable or method `foo' for main:Object
  2300. *
  2301. * Since constant names must start with a capital:
  2302. *
  2303. * Integer.const_set :answer, 42
  2304. *
  2305. * <em>raises the exception:</em>
  2306. *
  2307. * NameError: wrong constant name answer
  2308. */
  2309. /*
  2310. * Document-class: NoMethodError
  2311. *
  2312. * Raised when a method is called on a receiver which doesn't have it
  2313. * defined and also fails to respond with +method_missing+.
  2314. *
  2315. * "hello".to_ary
  2316. *
  2317. * <em>raises the exception:</em>
  2318. *
  2319. * NoMethodError: undefined method `to_ary' for "hello":String
  2320. */
  2321. /*
  2322. * Document-class: FrozenError
  2323. *
  2324. * Raised when there is an attempt to modify a frozen object.
  2325. *
  2326. * [1, 2, 3].freeze << 4
  2327. *
  2328. * <em>raises the exception:</em>
  2329. *
  2330. * FrozenError: can't modify frozen Array
  2331. */
  2332. /*
  2333. * Document-class: RuntimeError
  2334. *
  2335. * A generic error class raised when an invalid operation is attempted.
  2336. * Kernel#raise will raise a RuntimeError if no Exception class is
  2337. * specified.
  2338. *
  2339. * raise "ouch"
  2340. *
  2341. * <em>raises the exception:</em>
  2342. *
  2343. * RuntimeError: ouch
  2344. */
  2345. /*
  2346. * Document-class: SecurityError
  2347. *
  2348. * No longer used by internal code.
  2349. */
  2350. /*
  2351. * Document-class: NoMemoryError
  2352. *
  2353. * Raised when memory allocation fails.
  2354. */
  2355. /*
  2356. * Document-class: SystemCallError
  2357. *
  2358. * SystemCallError is the base class for all low-level
  2359. * platform-dependent errors.
  2360. *
  2361. * The errors available on the current platform are subclasses of
  2362. * SystemCallError and are defined in the Errno module.
  2363. *
  2364. * File.open("does/not/exist")
  2365. *
  2366. * <em>raises the exception:</em>
  2367. *
  2368. * Errno::ENOENT: No such file or directory - does/not/exist
  2369. */
  2370. /*
  2371. * Document-class: EncodingError
  2372. *
  2373. * EncodingError is the base class for encoding errors.
  2374. */
  2375. /*
  2376. * Document-class: Encoding::CompatibilityError
  2377. *
  2378. * Raised by Encoding and String methods when the source encoding is
  2379. * incompatible with the target encoding.
  2380. */
  2381. /*
  2382. * Document-class: fatal
  2383. *
  2384. * fatal is an Exception that is raised when Ruby has encountered a fatal
  2385. * error and must exit.
  2386. */
  2387. /*
  2388. * Document-class: NameError::message
  2389. * :nodoc:
  2390. */
  2391. /*
  2392. * Document-class: Exception
  2393. *
  2394. * \Class Exception and its subclasses are used to communicate between
  2395. * Kernel#raise and +rescue+ statements in <code>begin ... end</code> blocks.
  2396. *
  2397. * An Exception object carries information about an exception:
  2398. * - Its type (the exception's class).
  2399. * - An optional descriptive message.
  2400. * - Optional backtrace information.
  2401. *
  2402. * Some built-in subclasses of Exception have additional methods: e.g., NameError#name.
  2403. *
  2404. * == Defaults
  2405. *
  2406. * Two Ruby statements have default exception classes:
  2407. * - +raise+: defaults to RuntimeError.
  2408. * - +rescue+: defaults to StandardError.
  2409. *
  2410. * == Global Variables
  2411. *
  2412. * When an exception has been raised but not yet handled (in +rescue+,
  2413. * +ensure+, +at_exit+ and +END+ blocks), two global variables are set:
  2414. * - <code>$!</code> contains the current exception.
  2415. * - <code>$@</code> contains its backtrace.
  2416. *
  2417. * == Custom Exceptions
  2418. *
  2419. * To provide additional or alternate information,
  2420. * a program may create custom exception classes
  2421. * that derive from the built-in exception classes.
  2422. *
  2423. * A good practice is for a library to create a single "generic" exception class
  2424. * (typically a subclass of StandardError or RuntimeError)
  2425. * and have its other exception classes derive from that class.
  2426. * This allows the user to rescue the generic exception, thus catching all exceptions
  2427. * the library may raise even if future versions of the library add new
  2428. * exception subclasses.
  2429. *
  2430. * For example:
  2431. *
  2432. * class MyLibrary
  2433. * class Error < ::StandardError
  2434. * end
  2435. *
  2436. * class WidgetError < Error
  2437. * end
  2438. *
  2439. * class FrobError < Error
  2440. * end
  2441. *
  2442. * end
  2443. *
  2444. * To handle both MyLibrary::WidgetError and MyLibrary::FrobError the library
  2445. * user can rescue MyLibrary::Error.
  2446. *
  2447. * == Built-In Exception Classes
  2448. *
  2449. * The built-in subclasses of Exception are:
  2450. *
  2451. * * NoMemoryError
  2452. * * ScriptError
  2453. * * LoadError
  2454. * * NotImplementedError
  2455. * * SyntaxError
  2456. * * SecurityError
  2457. * * SignalException
  2458. * * Interrupt
  2459. * * StandardError
  2460. * * ArgumentError
  2461. * * UncaughtThrowError
  2462. * * EncodingError
  2463. * * FiberError
  2464. * * IOError
  2465. * * EOFError
  2466. * * IndexError
  2467. * * KeyError
  2468. * * StopIteration
  2469. * * ClosedQueueError
  2470. * * LocalJumpError
  2471. * * NameError
  2472. * * NoMethodError
  2473. * * RangeError
  2474. * * FloatDomainError
  2475. * * RegexpError
  2476. * * RuntimeError
  2477. * * FrozenError
  2478. * * SystemCallError
  2479. * * Errno::*
  2480. * * ThreadError
  2481. * * TypeError
  2482. * * ZeroDivisionError
  2483. * * SystemExit
  2484. * * SystemStackError
  2485. * * fatal
  2486. */
  2487. static VALUE
  2488. exception_alloc(VALUE klass)
  2489. {
  2490. return rb_class_allocate_instance(klass);
  2491. }
  2492. static VALUE
  2493. exception_dumper(VALUE exc)
  2494. {
  2495. // TODO: Currently, the instance variables "bt" and "bt_locations"
  2496. // refers to the same object (Array of String). But "bt_locations"
  2497. // should have an Array of Thread::Backtrace::Locations.
  2498. return exc;
  2499. }
  2500. static int
  2501. ivar_copy_i(st_data_t key, st_data_t val, st_data_t exc)
  2502. {
  2503. rb_ivar_set((VALUE) exc, (ID) key, (VALUE) val);
  2504. return ST_CONTINUE;
  2505. }
  2506. static VALUE
  2507. exception_loader(VALUE exc, VALUE obj)
  2508. {
  2509. // The loader function of rb_marshal_define_compat seems to be called for two events:
  2510. // one is for fixup (r_fixup_compat), the other is for TYPE_USERDEF.
  2511. // In the former case, the first argument is an instance of Exception (because
  2512. // we pass rb_eException to rb_marshal_define_compat). In the latter case, the first
  2513. // argument is a class object (see TYPE_USERDEF case in r_object0).
  2514. // We want to copy all instance variables (but "bt_locations") from obj to exc.
  2515. // But we do not want to do so in the second case, so the following branch is for that.
  2516. if (RB_TYPE_P(exc, T_CLASS)) return obj; // maybe called from Marshal's TYPE_USERDEF
  2517. rb_ivar_foreach(obj, ivar_copy_i, exc);
  2518. if (rb_attr_get(exc, id_bt) == rb_attr_get(exc, id_bt_locations)) {
  2519. rb_ivar_set(exc, id_bt_locations, Qnil);
  2520. }
  2521. return exc;
  2522. }
  2523. void
  2524. Init_Exception(void)
  2525. {
  2526. rb_eException = rb_define_class("Exception", rb_cObject);
  2527. rb_define_alloc_func(rb_eException, exception_alloc);
  2528. rb_marshal_define_compat(rb_eException, rb_eException, exception_dumper, exception_loader);
  2529. rb_define_singleton_method(rb_eException, "exception", rb_class_new_instance, -1);
  2530. rb_define_singleton_method(rb_eException, "to_tty?", exc_s_to_tty_p, 0);
  2531. rb_define_method(rb_eException, "exception", exc_exception, -1);
  2532. rb_define_method(rb_eException, "initialize", exc_initialize, -1);
  2533. rb_define_method(rb_eException, "==", exc_equal, 1);
  2534. rb_define_method(rb_eException, "to_s", exc_to_s, 0);
  2535. rb_define_method(rb_eException, "message", exc_message, 0);
  2536. rb_define_method(rb_eException, "full_message", exc_full_message, -1);
  2537. rb_define_method(rb_eException, "inspect", exc_inspect, 0);
  2538. rb_define_method(rb_eException, "backtrace", exc_backtrace, 0);
  2539. rb_define_method(rb_eException, "backtrace_locations", exc_backtrace_locations, 0);
  2540. rb_define_method(rb_eException, "set_backtrace", exc_set_backtrace, 1);
  2541. rb_define_method(rb_eException, "cause", exc_cause, 0);
  2542. rb_eSystemExit = rb_define_class("SystemExit", rb_eException);
  2543. rb_define_method(rb_eSystemExit, "initialize", exit_initialize, -1);
  2544. rb_define_method(rb_eSystemExit, "status", exit_status, 0);
  2545. rb_define_method(rb_eSystemExit, "success?", exit_success_p, 0);
  2546. rb_eFatal = rb_define_class("fatal", rb_eException);
  2547. rb_eSignal = rb_define_class("SignalException", rb_eException);
  2548. rb_eInterrupt = rb_define_class("Interrupt", rb_eSignal);
  2549. rb_eStandardError = rb_define_class("StandardError", rb_eException);
  2550. rb_eTypeError = rb_define_class("TypeError", rb_eStandardError);
  2551. rb_eArgError = rb_define_class("ArgumentError", rb_eStandardError);
  2552. rb_eIndexError = rb_define_class("IndexError", rb_eStandardError);
  2553. rb_eKeyError = rb_define_class("KeyError", rb_eIndexError);
  2554. rb_define_method(rb_eKeyError, "initialize", key_err_initialize, -1);
  2555. rb_define_method(rb_eKeyError, "receiver", key_err_receiver, 0);
  2556. rb_define_method(rb_eKeyError, "key", key_err_key, 0);
  2557. rb_eRangeError = rb_define_class("RangeError", rb_eStandardError);
  2558. rb_eScriptError = rb_define_class("ScriptError", rb_eException);
  2559. rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError);
  2560. rb_define_method(rb_eSyntaxError, "initialize", syntax_error_initialize, -1);
  2561. rb_eLoadError = rb_define_class("LoadError", rb_eScriptError);
  2562. /* the path failed to load */
  2563. rb_attr(rb_eLoadError, rb_intern_const("path"), 1, 0, Qfalse);
  2564. rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError);
  2565. rb_eNameError = rb_define_class("NameError", rb_eStandardError);
  2566. rb_define_method(rb_eNameError, "initialize", name_err_initialize, -1);
  2567. rb_define_method(rb_eNameError, "name", name_err_name, 0);
  2568. rb_define_method(rb_eNameError, "receiver", name_err_receiver, 0);
  2569. rb_define_method(rb_eNameError, "local_variables", name_err_local_variables, 0);
  2570. rb_cNameErrorMesg = rb_define_class_under(rb_eNameError, "message", rb_cObject);
  2571. rb_define_alloc_func(rb_cNameErrorMesg, name_err_mesg_alloc);
  2572. rb_define_method(rb_cNameErrorMesg, "initialize_copy", name_err_mesg_init_copy, 1);
  2573. rb_define_method(rb_cNameErrorMesg, "==", name_err_mesg_equal, 1);
  2574. rb_define_method(rb_cNameErrorMesg, "to_str", name_err_mesg_to_str, 0);
  2575. rb_define_method(rb_cNameErrorMesg, "_dump", name_err_mesg_dump, 1);
  2576. rb_define_singleton_method(rb_cNameErrorMesg, "_load", name_err_mesg_load, 1);
  2577. rb_eNoMethodError = rb_define_class("NoMethodError", rb_eNameError);
  2578. rb_define_method(rb_eNoMethodError, "initialize", nometh_err_initialize, -1);
  2579. rb_define_method(rb_eNoMethodError, "args", nometh_err_args, 0);
  2580. rb_define_method(rb_eNoMethodError, "private_call?", nometh_err_private_call_p, 0);
  2581. rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError);
  2582. rb_eFrozenError = rb_define_class("FrozenError", rb_eRuntimeError);
  2583. rb_define_method(rb_eFrozenError, "initialize", frozen_err_initialize, -1);
  2584. rb_define_method(rb_eFrozenError, "receiver", frozen_err_receiver, 0);
  2585. rb_eSecurityError = rb_define_class("SecurityError", rb_eException);
  2586. rb_eNoMemError = rb_define_class("NoMemoryError", rb_eException);
  2587. rb_eEncodingError = rb_define_class("EncodingError", rb_eStandardError);
  2588. rb_eEncCompatError = rb_define_class_under(rb_cEncoding, "CompatibilityError", rb_eEncodingError);
  2589. rb_eNoMatchingPatternError = rb_define_class("NoMatchingPatternError", rb_eStandardError);
  2590. rb_eNoMatchingPatternKeyError = rb_define_class("NoMatchingPatternKeyError", rb_eNoMatchingPatternError);
  2591. rb_define_method(rb_eNoMatchingPatternKeyError, "initialize", no_matching_pattern_key_err_initialize, -1);
  2592. rb_define_method(rb_eNoMatchingPatternKeyError, "matchee", no_matching_pattern_key_err_matchee, 0);
  2593. rb_define_method(rb_eNoMatchingPatternKeyError, "key", no_matching_pattern_key_err_key, 0);
  2594. syserr_tbl = st_init_numtable();
  2595. rb_eSystemCallError = rb_define_class("SystemCallError", rb_eStandardError);
  2596. rb_define_method(rb_eSystemCallError, "initialize", syserr_initialize, -1);
  2597. rb_define_method(rb_eSystemCallError, "errno", syserr_errno, 0);
  2598. rb_define_singleton_method(rb_eSystemCallError, "===", syserr_eqq, 1);
  2599. rb_mErrno = rb_define_module("Errno");
  2600. rb_mWarning = rb_define_module("Warning");
  2601. rb_define_singleton_method(rb_mWarning, "[]", rb_warning_s_aref, 1);
  2602. rb_define_singleton_method(rb_mWarning, "[]=", rb_warning_s_aset, 2);
  2603. rb_define_method(rb_mWarning, "warn", rb_warning_s_warn, -1);
  2604. rb_extend_object(rb_mWarning, rb_mWarning);
  2605. /* :nodoc: */
  2606. rb_cWarningBuffer = rb_define_class_under(rb_mWarning, "buffer", rb_cString);
  2607. rb_define_method(rb_cWarningBuffer, "write", warning_write, -1);
  2608. id_cause = rb_intern_const("cause");
  2609. id_message = rb_intern_const("message");
  2610. id_backtrace = rb_intern_const("backtrace");
  2611. id_key = rb_intern_const("key");
  2612. id_matchee = rb_intern_const("matchee");
  2613. id_args = rb_intern_const("args");
  2614. id_receiver = rb_intern_const("receiver");
  2615. id_private_call_p = rb_intern_const("private_call?");
  2616. id_local_variables = rb_intern_const("local_variables");
  2617. id_Errno = rb_intern_const("Errno");
  2618. id_errno = rb_intern_const("errno");
  2619. id_i_path = rb_intern_const("@path");
  2620. id_warn = rb_intern_const("warn");
  2621. id_category = rb_intern_const("category");
  2622. id_deprecated = rb_intern_const("deprecated");
  2623. id_experimental = rb_intern_const("experimental");
  2624. id_top = rb_intern_const("top");
  2625. id_bottom = rb_intern_const("bottom");
  2626. id_iseq = rb_make_internal_id();
  2627. id_recv = rb_make_internal_id();
  2628. sym_category = ID2SYM(id_category);
  2629. warning_categories.id2enum = rb_init_identtable();
  2630. st_add_direct(warning_categories.id2enum, id_deprecated, RB_WARN_CATEGORY_DEPRECATED);
  2631. st_add_direct(warning_categories.id2enum, id_experimental, RB_WARN_CATEGORY_EXPERIMENTAL);
  2632. warning_categories.enum2id = rb_init_identtable();
  2633. st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_NONE, 0);
  2634. st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_DEPRECATED, id_deprecated);
  2635. st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_EXPERIMENTAL, id_experimental);
  2636. }
  2637. void
  2638. rb_enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
  2639. {
  2640. va_list args;
  2641. VALUE mesg;
  2642. va_start(args, fmt);
  2643. mesg = rb_enc_vsprintf(enc, fmt, args);
  2644. va_end(args);
  2645. rb_exc_raise(rb_exc_new3(exc, mesg));
  2646. }
  2647. void
  2648. rb_vraise(VALUE exc, const char *fmt, va_list ap)
  2649. {
  2650. rb_exc_raise(rb_exc_new3(exc, rb_vsprintf(fmt, ap)));
  2651. }
  2652. void
  2653. rb_raise(VALUE exc, const char *fmt, ...)
  2654. {
  2655. va_list args;
  2656. va_start(args, fmt);
  2657. rb_vraise(exc, fmt, args);
  2658. va_end(args);
  2659. }
  2660. NORETURN(static void raise_loaderror(VALUE path, VALUE mesg));
  2661. static void
  2662. raise_loaderror(VALUE path, VALUE mesg)
  2663. {
  2664. VALUE err = rb_exc_new3(rb_eLoadError, mesg);
  2665. rb_ivar_set(err, id_i_path, path);
  2666. rb_exc_raise(err);
  2667. }
  2668. void
  2669. rb_loaderror(const char *fmt, ...)
  2670. {
  2671. va_list args;
  2672. VALUE mesg;
  2673. va_start(args, fmt);
  2674. mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args);
  2675. va_end(args);
  2676. raise_loaderror(Qnil, mesg);
  2677. }
  2678. void
  2679. rb_loaderror_with_path(VALUE path, const char *fmt, ...)
  2680. {
  2681. va_list args;
  2682. VALUE mesg;
  2683. va_start(args, fmt);
  2684. mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args);
  2685. va_end(args);
  2686. raise_loaderror(path, mesg);
  2687. }
  2688. void
  2689. rb_notimplement(void)
  2690. {
  2691. rb_raise(rb_eNotImpError,
  2692. "%"PRIsVALUE"() function is unimplemented on this machine",
  2693. rb_id2str(rb_frame_this_func()));
  2694. }
  2695. void
  2696. rb_fatal(const char *fmt, ...)
  2697. {
  2698. va_list args;
  2699. VALUE mesg;
  2700. if (! ruby_thread_has_gvl_p()) {
  2701. /* The thread has no GVL. Object allocation impossible (cant run GC),
  2702. * thus no message can be printed out. */
  2703. fprintf(stderr, "[FATAL] rb_fatal() outside of GVL\n");
  2704. rb_print_backtrace();
  2705. die();
  2706. }
  2707. va_start(args, fmt);
  2708. mesg = rb_vsprintf(fmt, args);
  2709. va_end(args);
  2710. rb_exc_fatal(rb_exc_new3(rb_eFatal, mesg));
  2711. }
  2712. static VALUE
  2713. make_errno_exc(const char *mesg)
  2714. {
  2715. int n = errno;
  2716. errno = 0;
  2717. if (n == 0) {
  2718. rb_bug("rb_sys_fail(%s) - errno == 0", mesg ? mesg : "");
  2719. }
  2720. return rb_syserr_new(n, mesg);
  2721. }
  2722. static VALUE
  2723. make_errno_exc_str(VALUE mesg)
  2724. {
  2725. int n = errno;
  2726. errno = 0;
  2727. if (!mesg) mesg = Qnil;
  2728. if (n == 0) {
  2729. const char *s = !NIL_P(mesg) ? RSTRING_PTR(mesg) : "";
  2730. rb_bug("rb_sys_fail_str(%s) - errno == 0", s);
  2731. }
  2732. return rb_syserr_new_str(n, mesg);
  2733. }
  2734. VALUE
  2735. rb_syserr_new(int n, const char *mesg)
  2736. {
  2737. VALUE arg;
  2738. arg = mesg ? rb_str_new2(mesg) : Qnil;
  2739. return rb_syserr_new_str(n, arg);
  2740. }
  2741. VALUE
  2742. rb_syserr_new_str(int n, VALUE arg)
  2743. {
  2744. return rb_class_new_instance(1, &arg, get_syserr(n));
  2745. }
  2746. void
  2747. rb_syserr_fail(int e, const char *mesg)
  2748. {
  2749. rb_exc_raise(rb_syserr_new(e, mesg));
  2750. }
  2751. void
  2752. rb_syserr_fail_str(int e, VALUE mesg)
  2753. {
  2754. rb_exc_raise(rb_syserr_new_str(e, mesg));
  2755. }
  2756. void
  2757. rb_sys_fail(const char *mesg)
  2758. {
  2759. rb_exc_raise(make_errno_exc(mesg));
  2760. }
  2761. void
  2762. rb_sys_fail_str(VALUE mesg)
  2763. {
  2764. rb_exc_raise(make_errno_exc_str(mesg));
  2765. }
  2766. #ifdef RUBY_FUNCTION_NAME_STRING
  2767. void
  2768. rb_sys_fail_path_in(const char *func_name, VALUE path)
  2769. {
  2770. int n = errno;
  2771. errno = 0;
  2772. rb_syserr_fail_path_in(func_name, n, path);
  2773. }
  2774. void
  2775. rb_syserr_fail_path_in(const char *func_name, int n, VALUE path)
  2776. {
  2777. rb_exc_raise(rb_syserr_new_path_in(func_name, n, path));
  2778. }
  2779. VALUE
  2780. rb_syserr_new_path_in(const char *func_name, int n, VALUE path)
  2781. {
  2782. VALUE args[2];
  2783. if (!path) path = Qnil;
  2784. if (n == 0) {
  2785. const char *s = !NIL_P(path) ? RSTRING_PTR(path) : "";
  2786. if (!func_name) func_name = "(null)";
  2787. rb_bug("rb_sys_fail_path_in(%s, %s) - errno == 0",
  2788. func_name, s);
  2789. }
  2790. args[0] = path;
  2791. args[1] = rb_str_new_cstr(func_name);
  2792. return rb_class_new_instance(2, args, get_syserr(n));
  2793. }
  2794. #endif
  2795. void
  2796. rb_mod_sys_fail(VALUE mod, const char *mesg)
  2797. {
  2798. VALUE exc = make_errno_exc(mesg);
  2799. rb_extend_object(exc, mod);
  2800. rb_exc_raise(exc);
  2801. }
  2802. void
  2803. rb_mod_sys_fail_str(VALUE mod, VALUE mesg)
  2804. {
  2805. VALUE exc = make_errno_exc_str(mesg);
  2806. rb_extend_object(exc, mod);
  2807. rb_exc_raise(exc);
  2808. }
  2809. void
  2810. rb_mod_syserr_fail(VALUE mod, int e, const char *mesg)
  2811. {
  2812. VALUE exc = rb_syserr_new(e, mesg);
  2813. rb_extend_object(exc, mod);
  2814. rb_exc_raise(exc);
  2815. }
  2816. void
  2817. rb_mod_syserr_fail_str(VALUE mod, int e, VALUE mesg)
  2818. {
  2819. VALUE exc = rb_syserr_new_str(e, mesg);
  2820. rb_extend_object(exc, mod);
  2821. rb_exc_raise(exc);
  2822. }
  2823. static void
  2824. syserr_warning(VALUE mesg, int err)
  2825. {
  2826. rb_str_set_len(mesg, RSTRING_LEN(mesg)-1);
  2827. rb_str_catf(mesg, ": %s\n", strerror(err));
  2828. rb_write_warning_str(mesg);
  2829. }
  2830. #if 0
  2831. void
  2832. rb_sys_warn(const char *fmt, ...)
  2833. {
  2834. if (!NIL_P(ruby_verbose)) {
  2835. int errno_save = errno;
  2836. with_warning_string(mesg, 0, fmt) {
  2837. syserr_warning(mesg, errno_save);
  2838. }
  2839. errno = errno_save;
  2840. }
  2841. }
  2842. void
  2843. rb_syserr_warn(int err, const char *fmt, ...)
  2844. {
  2845. if (!NIL_P(ruby_verbose)) {
  2846. with_warning_string(mesg, 0, fmt) {
  2847. syserr_warning(mesg, err);
  2848. }
  2849. }
  2850. }
  2851. void
  2852. rb_sys_enc_warn(rb_encoding *enc, const char *fmt, ...)
  2853. {
  2854. if (!NIL_P(ruby_verbose)) {
  2855. int errno_save = errno;
  2856. with_warning_string(mesg, enc, fmt) {
  2857. syserr_warning(mesg, errno_save);
  2858. }
  2859. errno = errno_save;
  2860. }
  2861. }
  2862. void
  2863. rb_syserr_enc_warn(int err, rb_encoding *enc, const char *fmt, ...)
  2864. {
  2865. if (!NIL_P(ruby_verbose)) {
  2866. with_warning_string(mesg, enc, fmt) {
  2867. syserr_warning(mesg, err);
  2868. }
  2869. }
  2870. }
  2871. #endif
  2872. void
  2873. rb_sys_warning(const char *fmt, ...)
  2874. {
  2875. if (RTEST(ruby_verbose)) {
  2876. int errno_save = errno;
  2877. with_warning_string(mesg, 0, fmt) {
  2878. syserr_warning(mesg, errno_save);
  2879. }
  2880. errno = errno_save;
  2881. }
  2882. }
  2883. #if 0
  2884. void
  2885. rb_syserr_warning(int err, const char *fmt, ...)
  2886. {
  2887. if (RTEST(ruby_verbose)) {
  2888. with_warning_string(mesg, 0, fmt) {
  2889. syserr_warning(mesg, err);
  2890. }
  2891. }
  2892. }
  2893. #endif
  2894. void
  2895. rb_sys_enc_warning(rb_encoding *enc, const char *fmt, ...)
  2896. {
  2897. if (RTEST(ruby_verbose)) {
  2898. int errno_save = errno;
  2899. with_warning_string(mesg, enc, fmt) {
  2900. syserr_warning(mesg, errno_save);
  2901. }
  2902. errno = errno_save;
  2903. }
  2904. }
  2905. void
  2906. rb_syserr_enc_warning(int err, rb_encoding *enc, const char *fmt, ...)
  2907. {
  2908. if (RTEST(ruby_verbose)) {
  2909. with_warning_string(mesg, enc, fmt) {
  2910. syserr_warning(mesg, err);
  2911. }
  2912. }
  2913. }
  2914. void
  2915. rb_load_fail(VALUE path, const char *err)
  2916. {
  2917. VALUE mesg = rb_str_buf_new_cstr(err);
  2918. rb_str_cat2(mesg, " -- ");
  2919. rb_str_append(mesg, path); /* should be ASCII compatible */
  2920. raise_loaderror(path, mesg);
  2921. }
  2922. void
  2923. rb_error_frozen(const char *what)
  2924. {
  2925. rb_raise(rb_eFrozenError, "can't modify frozen %s", what);
  2926. }
  2927. void
  2928. rb_frozen_error_raise(VALUE frozen_obj, const char *fmt, ...)
  2929. {
  2930. va_list args;
  2931. VALUE exc, mesg;
  2932. va_start(args, fmt);
  2933. mesg = rb_vsprintf(fmt, args);
  2934. va_end(args);
  2935. exc = rb_exc_new3(rb_eFrozenError, mesg);
  2936. rb_ivar_set(exc, id_recv, frozen_obj);
  2937. rb_exc_raise(exc);
  2938. }
  2939. static VALUE
  2940. inspect_frozen_obj(VALUE obj, VALUE mesg, int recur)
  2941. {
  2942. if (recur) {
  2943. rb_str_cat_cstr(mesg, " ...");
  2944. }
  2945. else {
  2946. rb_str_append(mesg, rb_inspect(obj));
  2947. }
  2948. return mesg;
  2949. }
  2950. void
  2951. rb_error_frozen_object(VALUE frozen_obj)
  2952. {
  2953. VALUE debug_info;
  2954. const ID created_info = id_debug_created_info;
  2955. VALUE mesg = rb_sprintf("can't modify frozen %"PRIsVALUE": ",
  2956. CLASS_OF(frozen_obj));
  2957. VALUE exc = rb_exc_new_str(rb_eFrozenError, mesg);
  2958. rb_ivar_set(exc, id_recv, frozen_obj);
  2959. rb_exec_recursive(inspect_frozen_obj, frozen_obj, mesg);
  2960. if (!NIL_P(debug_info = rb_attr_get(frozen_obj, created_info))) {
  2961. VALUE path = rb_ary_entry(debug_info, 0);
  2962. VALUE line = rb_ary_entry(debug_info, 1);
  2963. rb_str_catf(mesg, ", created at %"PRIsVALUE":%"PRIsVALUE, path, line);
  2964. }
  2965. rb_exc_raise(exc);
  2966. }
  2967. #undef rb_check_frozen
  2968. void
  2969. rb_check_frozen(VALUE obj)
  2970. {
  2971. rb_check_frozen_internal(obj);
  2972. }
  2973. void
  2974. rb_error_untrusted(VALUE obj)
  2975. {
  2976. rb_warn_deprecated_to_remove_at(3.2, "rb_error_untrusted", NULL);
  2977. }
  2978. #undef rb_check_trusted
  2979. void
  2980. rb_check_trusted(VALUE obj)
  2981. {
  2982. rb_warn_deprecated_to_remove_at(3.2, "rb_check_trusted", NULL);
  2983. }
  2984. void
  2985. rb_check_copyable(VALUE obj, VALUE orig)
  2986. {
  2987. if (!FL_ABLE(obj)) return;
  2988. rb_check_frozen_internal(obj);
  2989. if (!FL_ABLE(orig)) return;
  2990. }
  2991. void
  2992. Init_syserr(void)
  2993. {
  2994. rb_eNOERROR = set_syserr(0, "NOERROR");
  2995. #define defined_error(name, num) set_syserr((num), (name));
  2996. #define undefined_error(name) set_syserr(0, (name));
  2997. #include "known_errors.inc"
  2998. #undef defined_error
  2999. #undef undefined_error
  3000. }
  3001. #include "warning.rbinc"
  3002. /*!
  3003. * \}
  3004. */