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