Ruby 3.1.3p185 (2022-11-24 revision 1a6b16756e0ba6b95ab71a441357ed5484e33498)
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
64VALUE rb_iseqw_local_variables(VALUE iseqval);
65VALUE rb_iseqw_new(const rb_iseq_t *);
66int rb_str_end_with_asciichar(VALUE str, int c);
67
68long rb_backtrace_length_limit = -1;
69VALUE rb_eEAGAIN;
70VALUE rb_eEWOULDBLOCK;
71VALUE rb_eEINPROGRESS;
72static VALUE rb_mWarning;
73static VALUE rb_cWarningBuffer;
74
75static ID id_warn;
76static ID id_category;
77static ID id_deprecated;
78static ID id_experimental;
79static VALUE sym_category;
80static struct {
81 st_table *id2enum, *enum2id;
82} warning_categories;
83
84extern const char ruby_description[];
85
86static const char *
87rb_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
97static int
98err_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
111RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 5, 0)
112static VALUE
113err_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
126VALUE
127rb_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
154static unsigned int warning_disabled_categories = (
156 0);
157
158static unsigned int
159rb_warning_category_mask(VALUE category)
160{
161 return 1U << rb_warning_category_from_name(category);
162}
163
164rb_warning_category_t
165rb_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
177static VALUE
178rb_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
187void
188rb_warning_category_update(unsigned int mask, unsigned int bits)
189{
190 warning_disabled_categories &= ~mask;
191 warning_disabled_categories |= mask & ~bits;
192}
193
194MJIT_FUNC_EXPORTED bool
195rb_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
217static VALUE
218rb_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
232static VALUE
233rb_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
256static VALUE
257rb_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);
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
310static VALUE
311rb_warning_warn(VALUE mod, VALUE str)
312{
313 return rb_funcallv(mod, id_warn, 1, &str);
314}
315
316
317static int
318rb_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
324static VALUE
325rb_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
343static void
344rb_write_warning_str(VALUE str)
345{
346 rb_warning_warn(rb_mWarning, str);
347}
348
349RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 4, 0)
350static VALUE
351warn_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
359void
360rb_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 */
374void
375rb_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
388void
389rb_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
402RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 0)
403static VALUE
404warning_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
417void
418rb_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
427void
428rb_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
437void
438rb_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 */
448void
449rb_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 */
459void
460rb_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
469VALUE
470rb_warning_string(const char *fmt, ...)
471{
472 with_warning_string(mesg, 0, fmt) {
473 }
474 return mesg;
475}
476
477#if 0
478void
479rb_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
489static bool
490deprecation_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
497static void
498warn_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
510void
511rb_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
523void
524rb_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
536static inline int
537end_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: */
544static VALUE
545warning_write(int argc, VALUE *argv, VALUE buf)
546{
547 while (argc-- > 0) {
548 rb_str_append(buf, *argv++);
549 }
550 return buf;
551}
552
553VALUE rb_ec_backtrace_location_ary(const rb_execution_context_t *ec, long lev, long n, bool skip_internal);
554
555static VALUE
556rb_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) {
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
611static struct bug_reporters {
612 void (*func)(FILE *out, void *data);
613 void *data;
614} bug_reporters[MAX_BUG_REPORTERS];
615
616static int bug_reporters_size;
617
618int
619rb_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
634static FILE *
635bug_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
649FUNC_MINIMIZED(static void bug_important_message(FILE *out, const char *const msg, size_t len));
650
651static void
652bug_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
676static void
677preface_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
701static void
702postscript_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
723RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 0)
724static void
725bug_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
744static void
745bug_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
776NORETURN(static void die(void));
777static void
778die(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
787RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 0)
788void
789rb_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
801void
802rb_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
811void
812rb_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
829void
830rb_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
850void
851rb_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
872void
873rb_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
878MJIT_FUNC_EXPORTED void
879rb_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
891static 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
923const char *
924rb_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
933static VALUE
934displaying_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
944static const char *
945builtin_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
970const char *
971rb_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
981COLDFUNC NORETURN(static void unexpected_type(VALUE, int, int));
982#define UNDEF_LEAKED "undef leaked to the Ruby space"
983
984static void
985unexpected_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
1005void
1006rb_check_type(VALUE x, int t)
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
1028void
1029rb_unexpected_type(VALUE x, int t)
1030{
1031 if (RB_UNLIKELY(x == Qundef)) {
1032 rb_bug(UNDEF_LEAKED);
1033 }
1034
1035 unexpected_type(x, TYPE(x), t);
1036}
1037
1038int
1040{
1041 while (child) {
1042 if (child == parent) return 1;
1043 child = child->parent;
1044 }
1045 return 0;
1046}
1047
1048int
1049rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
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
1059int
1060rb_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
1065void *
1066rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
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
1121static VALUE rb_eNOERROR;
1122
1123ID ruby_static_id_cause;
1124#define id_cause ruby_static_id_cause
1125static ID id_message, id_backtrace;
1126static ID id_key, id_matchee, id_args, id_Errno, id_errno, id_i_path;
1127static ID id_receiver, id_recv, id_iseq, id_local_variables;
1128static 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
1136VALUE
1137rb_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
1143VALUE
1144rb_exc_new_cstr(VALUE etype, const char *s)
1145{
1146 return rb_exc_new(etype, s, strlen(s));
1147}
1148
1149VALUE
1150rb_exc_new_str(VALUE etype, VALUE str)
1151{
1152 StringValue(str);
1153 return rb_class_new_instance(1, &str, etype);
1154}
1155
1156static VALUE
1157exc_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
1174static VALUE
1175exc_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
1196static VALUE
1197exc_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
1217static VALUE
1218exc_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 */
1227void rb_error_write(VALUE errinfo, VALUE emesg, VALUE errat, VALUE str, VALUE highlight, VALUE reverse);
1228
1229VALUE
1230rb_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 */
1244static VALUE
1245exc_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
1268static VALUE
1269exc_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");
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
1321static VALUE
1322exc_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
1334static VALUE
1335exc_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
1390static VALUE
1391exc_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
1405static VALUE rb_check_backtrace(VALUE);
1406
1407VALUE
1408rb_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 */
1438static VALUE
1439exc_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
1450static VALUE
1451rb_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
1482static VALUE
1483exc_set_backtrace(VALUE exc, VALUE bt)
1484{
1485 return rb_ivar_set(exc, id_bt, rb_check_backtrace(bt));
1486}
1487
1488MJIT_FUNC_EXPORTED VALUE
1489rb_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
1503static VALUE
1504exc_cause(VALUE exc)
1505{
1506 return rb_attr_get(exc, id_cause);
1507}
1508
1509static VALUE
1510try_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
1524static VALUE
1525exc_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
1567static VALUE
1568exit_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
1617static VALUE
1618exit_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
1631static VALUE
1632exit_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
1643static VALUE
1644err_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
1662static VALUE
1663frozen_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
1686void
1687rb_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
1701void
1702rb_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
1716static VALUE
1717name_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
1741static VALUE
1742name_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
1756static VALUE rb_name_err_mesg_new(VALUE mesg, VALUE recv, VALUE method);
1757
1758static VALUE
1759name_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
1765VALUE
1766rb_name_err_new(VALUE mesg, VALUE recv, VALUE method)
1767{
1768 VALUE exc = rb_obj_alloc(rb_eNameError);
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
1779static VALUE
1780name_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
1795static VALUE
1796name_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
1809static VALUE
1810nometh_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
1833static VALUE
1834nometh_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
1846VALUE
1847rb_nomethod_err_new(VALUE mesg, VALUE recv, VALUE method, VALUE args, int priv)
1848{
1849 VALUE exc = rb_obj_alloc(rb_eNoMethodError);
1850 name_err_init(exc, mesg, recv, method);
1851 return nometh_err_init_attr(exc, args, priv);
1852}
1853
1854/* :nodoc: */
1855enum {
1856 NAME_ERR_MESG__MESG,
1857 NAME_ERR_MESG__RECV,
1858 NAME_ERR_MESG__NAME,
1859 NAME_ERR_MESG_COUNT
1860};
1861
1862static void
1863name_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
1871static size_t
1872name_err_mesg_memsize(const void *p)
1873{
1874 return NAME_ERR_MESG_COUNT * sizeof(VALUE);
1875}
1876
1877static 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: */
1888static VALUE
1889rb_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: */
1902static VALUE
1903rb_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: */
1909static VALUE
1910name_err_mesg_alloc(VALUE klass)
1911{
1912 return rb_name_err_mesg_init(klass, Qnil, Qnil, Qnil);
1913}
1914
1915/* :nodoc: */
1916static VALUE
1917name_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: */
1931static VALUE
1932name_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: */
1951static VALUE
1952name_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: */
1962static VALUE
1963name_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: */
2019static VALUE
2020name_err_mesg_dump(VALUE obj, VALUE limit)
2021{
2022 return name_err_mesg_to_str(obj);
2023}
2024
2025/* :nodoc: */
2026static VALUE
2027name_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
2039static VALUE
2040name_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
2063static VALUE
2064nometh_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
2076static VALUE
2077nometh_err_private_call_p(VALUE self)
2078{
2079 return rb_attr_get(self, id_private_call_p);
2080}
2081
2082void
2083rb_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
2097static VALUE
2098key_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
2114static VALUE
2115key_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
2124VALUE
2125rb_key_err_new(VALUE mesg, VALUE recv, VALUE key)
2126{
2127 VALUE exc = rb_obj_alloc(rb_eKeyError);
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
2143static VALUE
2144key_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
2174static VALUE
2175no_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
2191static VALUE
2192no_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
2209static VALUE
2210no_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
2241static VALUE
2242syntax_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
2283static st_table *syserr_tbl;
2284
2285static VALUE
2286set_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
2319static VALUE
2320get_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
2343static VALUE
2344syserr_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
2396static VALUE
2397syserr_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
2410static VALUE
2411syserr_eqq(VALUE self, VALUE exc)
2412{
2413 VALUE num, e;
2414
2415 if (!rb_obj_is_kind_of(exc, rb_eSystemCallError)) {
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
2826static VALUE
2827exception_alloc(VALUE klass)
2828{
2829 return rb_class_allocate_instance(klass);
2830}
2831
2832static VALUE
2833exception_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
2842static int
2843ivar_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
2849static VALUE
2850exception_loader(VALUE exc, VALUE obj)
2851{
2852 // The loader function of rb_marshal_define_compat seems to be called for two events:
2853 // one is for fixup (r_fixup_compat), the other is for TYPE_USERDEF.
2854 // In the former case, the first argument is an instance of Exception (because
2855 // we pass rb_eException to rb_marshal_define_compat). In the latter case, the first
2856 // argument is a class object (see TYPE_USERDEF case in r_object0).
2857 // We want to copy all instance variables (but "bt_locations") from obj to exc.
2858 // But we do not want to do so in the second case, so the following branch is for that.
2859 if (RB_TYPE_P(exc, T_CLASS)) return obj; // maybe called from Marshal's TYPE_USERDEF
2860
2861 rb_ivar_foreach(obj, ivar_copy_i, exc);
2862
2863 if (rb_attr_get(exc, id_bt) == rb_attr_get(exc, id_bt_locations)) {
2864 rb_ivar_set(exc, id_bt_locations, Qnil);
2865 }
2866
2867 return exc;
2868}
2869
2870void
2871Init_Exception(void)
2872{
2873 rb_eException = rb_define_class("Exception", rb_cObject);
2874 rb_define_alloc_func(rb_eException, exception_alloc);
2875 rb_marshal_define_compat(rb_eException, rb_eException, exception_dumper, exception_loader);
2876 rb_define_singleton_method(rb_eException, "exception", rb_class_new_instance, -1);
2877 rb_define_singleton_method(rb_eException, "to_tty?", exc_s_to_tty_p, 0);
2878 rb_define_method(rb_eException, "exception", exc_exception, -1);
2879 rb_define_method(rb_eException, "initialize", exc_initialize, -1);
2880 rb_define_method(rb_eException, "==", exc_equal, 1);
2881 rb_define_method(rb_eException, "to_s", exc_to_s, 0);
2882 rb_define_method(rb_eException, "message", exc_message, 0);
2883 rb_define_method(rb_eException, "full_message", exc_full_message, -1);
2884 rb_define_method(rb_eException, "inspect", exc_inspect, 0);
2885 rb_define_method(rb_eException, "backtrace", exc_backtrace, 0);
2886 rb_define_method(rb_eException, "backtrace_locations", exc_backtrace_locations, 0);
2887 rb_define_method(rb_eException, "set_backtrace", exc_set_backtrace, 1);
2888 rb_define_method(rb_eException, "cause", exc_cause, 0);
2889
2891 rb_define_method(rb_eSystemExit, "initialize", exit_initialize, -1);
2892 rb_define_method(rb_eSystemExit, "status", exit_status, 0);
2893 rb_define_method(rb_eSystemExit, "success?", exit_success_p, 0);
2894
2896 rb_eSignal = rb_define_class("SignalException", rb_eException);
2898
2904 rb_define_method(rb_eKeyError, "initialize", key_err_initialize, -1);
2905 rb_define_method(rb_eKeyError, "receiver", key_err_receiver, 0);
2906 rb_define_method(rb_eKeyError, "key", key_err_key, 0);
2908
2911 rb_define_method(rb_eSyntaxError, "initialize", syntax_error_initialize, -1);
2912
2914 /* the path failed to load */
2916
2917 rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError);
2918
2920 rb_define_method(rb_eNameError, "initialize", name_err_initialize, -1);
2921 rb_define_method(rb_eNameError, "name", name_err_name, 0);
2922 rb_define_method(rb_eNameError, "receiver", name_err_receiver, 0);
2923 rb_define_method(rb_eNameError, "local_variables", name_err_local_variables, 0);
2924 rb_cNameErrorMesg = rb_define_class_under(rb_eNameError, "message", rb_cObject);
2925 rb_define_alloc_func(rb_cNameErrorMesg, name_err_mesg_alloc);
2926 rb_define_method(rb_cNameErrorMesg, "initialize_copy", name_err_mesg_init_copy, 1);
2927 rb_define_method(rb_cNameErrorMesg, "==", name_err_mesg_equal, 1);
2928 rb_define_method(rb_cNameErrorMesg, "to_str", name_err_mesg_to_str, 0);
2929 rb_define_method(rb_cNameErrorMesg, "_dump", name_err_mesg_dump, 1);
2930 rb_define_singleton_method(rb_cNameErrorMesg, "_load", name_err_mesg_load, 1);
2932 rb_define_method(rb_eNoMethodError, "initialize", nometh_err_initialize, -1);
2933 rb_define_method(rb_eNoMethodError, "args", nometh_err_args, 0);
2934 rb_define_method(rb_eNoMethodError, "private_call?", nometh_err_private_call_p, 0);
2935
2938 rb_define_method(rb_eFrozenError, "initialize", frozen_err_initialize, -1);
2939 rb_define_method(rb_eFrozenError, "receiver", frozen_err_receiver, 0);
2941 rb_eNoMemError = rb_define_class("NoMemoryError", rb_eException);
2946 rb_define_method(rb_eNoMatchingPatternKeyError, "initialize", no_matching_pattern_key_err_initialize, -1);
2947 rb_define_method(rb_eNoMatchingPatternKeyError, "matchee", no_matching_pattern_key_err_matchee, 0);
2948 rb_define_method(rb_eNoMatchingPatternKeyError, "key", no_matching_pattern_key_err_key, 0);
2949
2950 syserr_tbl = st_init_numtable();
2952 rb_define_method(rb_eSystemCallError, "initialize", syserr_initialize, -1);
2953 rb_define_method(rb_eSystemCallError, "errno", syserr_errno, 0);
2954 rb_define_singleton_method(rb_eSystemCallError, "===", syserr_eqq, 1);
2955
2956 rb_mErrno = rb_define_module("Errno");
2957
2958 rb_mWarning = rb_define_module("Warning");
2959 rb_define_singleton_method(rb_mWarning, "[]", rb_warning_s_aref, 1);
2960 rb_define_singleton_method(rb_mWarning, "[]=", rb_warning_s_aset, 2);
2961 rb_define_method(rb_mWarning, "warn", rb_warning_s_warn, -1);
2962 rb_extend_object(rb_mWarning, rb_mWarning);
2963
2964 /* :nodoc: */
2965 rb_cWarningBuffer = rb_define_class_under(rb_mWarning, "buffer", rb_cString);
2966 rb_define_method(rb_cWarningBuffer, "write", warning_write, -1);
2967
2968 id_cause = rb_intern_const("cause");
2969 id_message = rb_intern_const("message");
2970 id_backtrace = rb_intern_const("backtrace");
2971 id_key = rb_intern_const("key");
2972 id_matchee = rb_intern_const("matchee");
2973 id_args = rb_intern_const("args");
2974 id_receiver = rb_intern_const("receiver");
2975 id_private_call_p = rb_intern_const("private_call?");
2976 id_local_variables = rb_intern_const("local_variables");
2977 id_Errno = rb_intern_const("Errno");
2978 id_errno = rb_intern_const("errno");
2979 id_i_path = rb_intern_const("@path");
2980 id_warn = rb_intern_const("warn");
2981 id_category = rb_intern_const("category");
2982 id_deprecated = rb_intern_const("deprecated");
2983 id_experimental = rb_intern_const("experimental");
2984 id_top = rb_intern_const("top");
2985 id_bottom = rb_intern_const("bottom");
2986 id_iseq = rb_make_internal_id();
2987 id_recv = rb_make_internal_id();
2988
2989 sym_category = ID2SYM(id_category);
2990
2991 warning_categories.id2enum = rb_init_identtable();
2992 st_add_direct(warning_categories.id2enum, id_deprecated, RB_WARN_CATEGORY_DEPRECATED);
2993 st_add_direct(warning_categories.id2enum, id_experimental, RB_WARN_CATEGORY_EXPERIMENTAL);
2994
2995 warning_categories.enum2id = rb_init_identtable();
2996 st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_NONE, 0);
2997 st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_DEPRECATED, id_deprecated);
2998 st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_EXPERIMENTAL, id_experimental);
2999}
3000
3001void
3002rb_enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
3003{
3004 va_list args;
3005 VALUE mesg;
3006
3007 va_start(args, fmt);
3008 mesg = rb_enc_vsprintf(enc, fmt, args);
3009 va_end(args);
3010
3011 rb_exc_raise(rb_exc_new3(exc, mesg));
3012}
3013
3014void
3015rb_vraise(VALUE exc, const char *fmt, va_list ap)
3016{
3017 rb_exc_raise(rb_exc_new3(exc, rb_vsprintf(fmt, ap)));
3018}
3019
3020void
3021rb_raise(VALUE exc, const char *fmt, ...)
3022{
3023 va_list args;
3024 va_start(args, fmt);
3025 rb_vraise(exc, fmt, args);
3026 va_end(args);
3027}
3028
3029NORETURN(static void raise_loaderror(VALUE path, VALUE mesg));
3030
3031static void
3032raise_loaderror(VALUE path, VALUE mesg)
3033{
3034 VALUE err = rb_exc_new3(rb_eLoadError, mesg);
3035 rb_ivar_set(err, id_i_path, path);
3036 rb_exc_raise(err);
3037}
3038
3039void
3040rb_loaderror(const char *fmt, ...)
3041{
3042 va_list args;
3043 VALUE mesg;
3044
3045 va_start(args, fmt);
3046 mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args);
3047 va_end(args);
3048 raise_loaderror(Qnil, mesg);
3049}
3050
3051void
3052rb_loaderror_with_path(VALUE path, const char *fmt, ...)
3053{
3054 va_list args;
3055 VALUE mesg;
3056
3057 va_start(args, fmt);
3058 mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args);
3059 va_end(args);
3060 raise_loaderror(path, mesg);
3061}
3062
3063void
3065{
3067 "%"PRIsVALUE"() function is unimplemented on this machine",
3069}
3070
3071void
3072rb_fatal(const char *fmt, ...)
3073{
3074 va_list args;
3075 VALUE mesg;
3076
3077 if (! ruby_thread_has_gvl_p()) {
3078 /* The thread has no GVL. Object allocation impossible (cant run GC),
3079 * thus no message can be printed out. */
3080 fprintf(stderr, "[FATAL] rb_fatal() outside of GVL\n");
3081 rb_print_backtrace();
3082 die();
3083 }
3084
3085 va_start(args, fmt);
3086 mesg = rb_vsprintf(fmt, args);
3087 va_end(args);
3088
3090}
3091
3092static VALUE
3093make_errno_exc(const char *mesg)
3094{
3095 int n = errno;
3096
3097 errno = 0;
3098 if (n == 0) {
3099 rb_bug("rb_sys_fail(%s) - errno == 0", mesg ? mesg : "");
3100 }
3101 return rb_syserr_new(n, mesg);
3102}
3103
3104static VALUE
3105make_errno_exc_str(VALUE mesg)
3106{
3107 int n = errno;
3108
3109 errno = 0;
3110 if (!mesg) mesg = Qnil;
3111 if (n == 0) {
3112 const char *s = !NIL_P(mesg) ? RSTRING_PTR(mesg) : "";
3113 rb_bug("rb_sys_fail_str(%s) - errno == 0", s);
3114 }
3115 return rb_syserr_new_str(n, mesg);
3116}
3117
3118VALUE
3119rb_syserr_new(int n, const char *mesg)
3120{
3121 VALUE arg;
3122 arg = mesg ? rb_str_new2(mesg) : Qnil;
3123 return rb_syserr_new_str(n, arg);
3124}
3125
3126VALUE
3127rb_syserr_new_str(int n, VALUE arg)
3128{
3129 return rb_class_new_instance(1, &arg, get_syserr(n));
3130}
3131
3132void
3133rb_syserr_fail(int e, const char *mesg)
3134{
3135 rb_exc_raise(rb_syserr_new(e, mesg));
3136}
3137
3138void
3139rb_syserr_fail_str(int e, VALUE mesg)
3140{
3142}
3143
3144void
3145rb_sys_fail(const char *mesg)
3146{
3147 rb_exc_raise(make_errno_exc(mesg));
3148}
3149
3150void
3152{
3153 rb_exc_raise(make_errno_exc_str(mesg));
3154}
3155
3156#ifdef RUBY_FUNCTION_NAME_STRING
3157void
3158rb_sys_fail_path_in(const char *func_name, VALUE path)
3159{
3160 int n = errno;
3161
3162 errno = 0;
3163 rb_syserr_fail_path_in(func_name, n, path);
3164}
3165
3166void
3167rb_syserr_fail_path_in(const char *func_name, int n, VALUE path)
3168{
3169 rb_exc_raise(rb_syserr_new_path_in(func_name, n, path));
3170}
3171
3172VALUE
3173rb_syserr_new_path_in(const char *func_name, int n, VALUE path)
3174{
3175 VALUE args[2];
3176
3177 if (!path) path = Qnil;
3178 if (n == 0) {
3179 const char *s = !NIL_P(path) ? RSTRING_PTR(path) : "";
3180 if (!func_name) func_name = "(null)";
3181 rb_bug("rb_sys_fail_path_in(%s, %s) - errno == 0",
3182 func_name, s);
3183 }
3184 args[0] = path;
3185 args[1] = rb_str_new_cstr(func_name);
3186 return rb_class_new_instance(2, args, get_syserr(n));
3187}
3188#endif
3189
3190NORETURN(static void rb_mod_exc_raise(VALUE exc, VALUE mod));
3191
3192static void
3193rb_mod_exc_raise(VALUE exc, VALUE mod)
3194{
3195 rb_extend_object(exc, mod);
3196 rb_exc_raise(exc);
3197}
3198
3199void
3200rb_mod_sys_fail(VALUE mod, const char *mesg)
3201{
3202 VALUE exc = make_errno_exc(mesg);
3203 rb_mod_exc_raise(exc, mod);
3204}
3205
3206void
3207rb_mod_sys_fail_str(VALUE mod, VALUE mesg)
3208{
3209 VALUE exc = make_errno_exc_str(mesg);
3210 rb_mod_exc_raise(exc, mod);
3211}
3212
3213void
3214rb_mod_syserr_fail(VALUE mod, int e, const char *mesg)
3215{
3216 VALUE exc = rb_syserr_new(e, mesg);
3217 rb_mod_exc_raise(exc, mod);
3218}
3219
3220void
3221rb_mod_syserr_fail_str(VALUE mod, int e, VALUE mesg)
3222{
3223 VALUE exc = rb_syserr_new_str(e, mesg);
3224 rb_mod_exc_raise(exc, mod);
3225}
3226
3227static void
3228syserr_warning(VALUE mesg, int err)
3229{
3230 rb_str_set_len(mesg, RSTRING_LEN(mesg)-1);
3231 rb_str_catf(mesg, ": %s\n", strerror(err));
3232 rb_write_warning_str(mesg);
3233}
3234
3235#if 0
3236void
3237rb_sys_warn(const char *fmt, ...)
3238{
3239 if (!NIL_P(ruby_verbose)) {
3240 int errno_save = errno;
3241 with_warning_string(mesg, 0, fmt) {
3242 syserr_warning(mesg, errno_save);
3243 }
3244 errno = errno_save;
3245 }
3246}
3247
3248void
3249rb_syserr_warn(int err, const char *fmt, ...)
3250{
3251 if (!NIL_P(ruby_verbose)) {
3252 with_warning_string(mesg, 0, fmt) {
3253 syserr_warning(mesg, err);
3254 }
3255 }
3256}
3257
3258void
3259rb_sys_enc_warn(rb_encoding *enc, const char *fmt, ...)
3260{
3261 if (!NIL_P(ruby_verbose)) {
3262 int errno_save = errno;
3263 with_warning_string(mesg, enc, fmt) {
3264 syserr_warning(mesg, errno_save);
3265 }
3266 errno = errno_save;
3267 }
3268}
3269
3270void
3271rb_syserr_enc_warn(int err, rb_encoding *enc, const char *fmt, ...)
3272{
3273 if (!NIL_P(ruby_verbose)) {
3274 with_warning_string(mesg, enc, fmt) {
3275 syserr_warning(mesg, err);
3276 }
3277 }
3278}
3279#endif
3280
3281void
3282rb_sys_warning(const char *fmt, ...)
3283{
3284 if (RTEST(ruby_verbose)) {
3285 int errno_save = errno;
3286 with_warning_string(mesg, 0, fmt) {
3287 syserr_warning(mesg, errno_save);
3288 }
3289 errno = errno_save;
3290 }
3291}
3292
3293#if 0
3294void
3295rb_syserr_warning(int err, const char *fmt, ...)
3296{
3297 if (RTEST(ruby_verbose)) {
3298 with_warning_string(mesg, 0, fmt) {
3299 syserr_warning(mesg, err);
3300 }
3301 }
3302}
3303#endif
3304
3305void
3306rb_sys_enc_warning(rb_encoding *enc, const char *fmt, ...)
3307{
3308 if (RTEST(ruby_verbose)) {
3309 int errno_save = errno;
3310 with_warning_string(mesg, enc, fmt) {
3311 syserr_warning(mesg, errno_save);
3312 }
3313 errno = errno_save;
3314 }
3315}
3316
3317void
3318rb_syserr_enc_warning(int err, rb_encoding *enc, const char *fmt, ...)
3319{
3320 if (RTEST(ruby_verbose)) {
3321 with_warning_string(mesg, enc, fmt) {
3322 syserr_warning(mesg, err);
3323 }
3324 }
3325}
3326
3327void
3328rb_load_fail(VALUE path, const char *err)
3329{
3330 VALUE mesg = rb_str_buf_new_cstr(err);
3331 rb_str_cat2(mesg, " -- ");
3332 rb_str_append(mesg, path); /* should be ASCII compatible */
3333 raise_loaderror(path, mesg);
3334}
3335
3336void
3337rb_error_frozen(const char *what)
3338{
3339 rb_raise(rb_eFrozenError, "can't modify frozen %s", what);
3340}
3341
3342void
3343rb_frozen_error_raise(VALUE frozen_obj, const char *fmt, ...)
3344{
3345 va_list args;
3346 VALUE exc, mesg;
3347
3348 va_start(args, fmt);
3349 mesg = rb_vsprintf(fmt, args);
3350 va_end(args);
3351 exc = rb_exc_new3(rb_eFrozenError, mesg);
3352 rb_ivar_set(exc, id_recv, frozen_obj);
3353 rb_exc_raise(exc);
3354}
3355
3356static VALUE
3357inspect_frozen_obj(VALUE obj, VALUE mesg, int recur)
3358{
3359 if (recur) {
3360 rb_str_cat_cstr(mesg, " ...");
3361 }
3362 else {
3363 rb_str_append(mesg, rb_inspect(obj));
3364 }
3365 return mesg;
3366}
3367
3368void
3369rb_error_frozen_object(VALUE frozen_obj)
3370{
3371 VALUE debug_info;
3372 const ID created_info = id_debug_created_info;
3373 VALUE mesg = rb_sprintf("can't modify frozen %"PRIsVALUE": ",
3374 CLASS_OF(frozen_obj));
3375 VALUE exc = rb_exc_new_str(rb_eFrozenError, mesg);
3376
3377 rb_ivar_set(exc, id_recv, frozen_obj);
3378 rb_exec_recursive(inspect_frozen_obj, frozen_obj, mesg);
3379
3380 if (!NIL_P(debug_info = rb_attr_get(frozen_obj, created_info))) {
3381 VALUE path = rb_ary_entry(debug_info, 0);
3382 VALUE line = rb_ary_entry(debug_info, 1);
3383
3384 rb_str_catf(mesg, ", created at %"PRIsVALUE":%"PRIsVALUE, path, line);
3385 }
3386 rb_exc_raise(exc);
3387}
3388
3389#undef rb_check_frozen
3390void
3392{
3394}
3395
3396void
3398{
3399 rb_warn_deprecated_to_remove_at(3.2, "rb_error_untrusted", NULL);
3400}
3401
3402#undef rb_check_trusted
3403void
3405{
3406 rb_warn_deprecated_to_remove_at(3.2, "rb_check_trusted", NULL);
3407}
3408
3409void
3410rb_check_copyable(VALUE obj, VALUE orig)
3411{
3412 if (!FL_ABLE(obj)) return;
3414 if (!FL_ABLE(orig)) return;
3415}
3416
3417void
3418Init_syserr(void)
3419{
3420 rb_eNOERROR = set_syserr(0, "NOERROR");
3421#define defined_error(name, num) set_syserr((num), (name));
3422#define undefined_error(name) set_syserr(0, (name));
3423#include "known_errors.inc"
3424#undef defined_error
3425#undef undefined_error
3426}
3427
3428#include "warning.rbinc"
3429
#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:1579
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:3064
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:3200
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:3021
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:3214
void rb_check_frozen(VALUE obj)
Queries if the passed object is frozen.
Definition: error.c:3391
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:671
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:3133
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:3145
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:3282
void rb_check_copyable(VALUE obj, VALUE orig)
Ensures that the passed object can be initialize_copy relationship.
Definition: error.c:3410
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:3127
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:3221
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:3337
void rb_set_errinfo(VALUE err)
Sets the current exception ($!) to the given value.
Definition: eval.c:1760
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:3397
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:3139
#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:3072
void rb_frozen_error_raise(VALUE frozen_obj, const char *fmt,...)
Raises an instance of rb_eFrozenError.
Definition: error.c:3343
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:684
VALUE rb_eRuntimeError
RuntimeError exception.
Definition: error.c:1097
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
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:3369
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:3002
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:3040
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:3052
void rb_check_trusted(VALUE obj)
Definition: error.c:3404
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:3119
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:3151
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:3207
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_obj_init_copy(VALUE src, VALUE dst)
Default implementation of #initialize_copy.
Definition: object.c:500
VALUE rb_cEncoding
Encoding class.
Definition: encoding.c:57
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:1035
void rb_gc_mark_locations(const VALUE *start, const VALUE *end)
Marks objects between the two pointers.
Definition: gc.c:6208
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... Let us hesitate from describing what a "basic definition" is.
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 long RSTRING_LEN(VALUE str)
Queries the length of the string.
Definition: rstring.h:483
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 char * RSTRING_PTR(VALUE str)
Queries the contents pointer of the string.
Definition: rstring.h:497
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.
char * ptr
Pointer to the contents of the string.
This is the struct that holds necessary info for a struct.
const char * wrap_struct_name
Name of structs of this kind.
const rb_data_type_t * parent
Parent of this class.
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