2000-05-01 13:42:38 +04:00
|
|
|
/**********************************************************************
|
1998-01-16 15:13:05 +03:00
|
|
|
|
|
|
|
error.c -
|
|
|
|
|
|
|
|
$Author$
|
|
|
|
created at: Mon Aug 9 16:11:34 JST 1993
|
|
|
|
|
* encoding.c: provide basic features for M17N.
* parse.y: encoding aware parsing.
* parse.y (pragma_encoding): encoding specification pragma.
* parse.y (rb_intern3): encoding specified symbols.
* string.c (rb_str_length): length based on characters.
for older behavior, bytesize method added.
* string.c (rb_str_index_m): index based on characters. rindex as
well.
* string.c (succ_char): encoding aware succeeding string.
* string.c (rb_str_reverse): reverse based on characters.
* string.c (rb_str_inspect): encoding aware string description.
* string.c (rb_str_upcase_bang): encoding aware case conversion.
downcase, capitalize, swapcase as well.
* string.c (rb_str_tr_bang): tr based on characters. delete,
squeeze, tr_s, count as well.
* string.c (rb_str_split_m): split based on characters.
* string.c (rb_str_each_line): encoding aware each_line.
* string.c (rb_str_each_char): added. iteration based on
characters.
* string.c (rb_str_strip_bang): encoding aware whitespace
stripping. lstrip, rstrip as well.
* string.c (rb_str_justify): encoding aware justifying (ljust,
rjust, center).
* string.c (str_encoding): get encoding attribute from a string.
* re.c (rb_reg_initialize): encoding aware regular expression
* sprintf.c (rb_str_format): formatting (i.e. length count) based
on characters.
* io.c (rb_io_getc): getc to return one-character string.
for older behavior, getbyte method added.
* ext/stringio/stringio.c (strio_getc): ditto.
* io.c (rb_io_ungetc): allow pushing arbitrary string at the
current reading point.
* ext/stringio/stringio.c (strio_ungetc): ditto.
* ext/strscan/strscan.c: encoding support.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13261 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-25 07:29:39 +04:00
|
|
|
Copyright (C) 1993-2007 Yukihiro Matsumoto
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2000-05-01 13:42:38 +04:00
|
|
|
**********************************************************************/
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2020-05-08 12:31:09 +03:00
|
|
|
#include "ruby/internal/config.h"
|
2000-11-14 10:10:31 +03:00
|
|
|
|
2019-12-04 11:16:30 +03:00
|
|
|
#include <errno.h>
|
1999-01-20 07:59:39 +03:00
|
|
|
#include <stdarg.h>
|
2019-12-04 11:16:30 +03:00
|
|
|
#include <stdio.h>
|
|
|
|
|
2004-07-16 06:17:59 +04:00
|
|
|
#ifdef HAVE_STDLIB_H
|
2019-12-04 11:16:30 +03:00
|
|
|
# include <stdlib.h>
|
2004-07-16 06:17:59 +04:00
|
|
|
#endif
|
2019-12-04 11:16:30 +03:00
|
|
|
|
2011-06-29 01:17:29 +04:00
|
|
|
#ifdef HAVE_UNISTD_H
|
2019-12-04 11:16:30 +03:00
|
|
|
# include <unistd.h>
|
2011-06-29 01:17:29 +04:00
|
|
|
#endif
|
2009-11-24 15:26:06 +03:00
|
|
|
|
2023-08-05 16:11:52 +03:00
|
|
|
#ifdef HAVE_SYS_WAIT_H
|
|
|
|
# include <sys/wait.h>
|
|
|
|
#endif
|
|
|
|
|
2017-01-13 06:24:22 +03:00
|
|
|
#if defined __APPLE__
|
|
|
|
# include <AvailabilityMacros.h>
|
|
|
|
#endif
|
|
|
|
|
2019-12-04 11:16:30 +03:00
|
|
|
#include "internal.h"
|
2024-03-06 19:04:22 +03:00
|
|
|
#include "internal/class.h"
|
2019-12-04 11:16:30 +03:00
|
|
|
#include "internal/error.h"
|
|
|
|
#include "internal/eval.h"
|
2020-12-24 04:27:59 +03:00
|
|
|
#include "internal/hash.h"
|
2019-12-04 11:16:30 +03:00
|
|
|
#include "internal/io.h"
|
|
|
|
#include "internal/load.h"
|
|
|
|
#include "internal/object.h"
|
2023-08-05 16:11:52 +03:00
|
|
|
#include "internal/process.h"
|
2022-09-23 10:40:59 +03:00
|
|
|
#include "internal/string.h"
|
2019-12-04 11:16:30 +03:00
|
|
|
#include "internal/symbol.h"
|
|
|
|
#include "internal/thread.h"
|
|
|
|
#include "internal/variable.h"
|
|
|
|
#include "ruby/encoding.h"
|
|
|
|
#include "ruby/st.h"
|
2023-08-05 16:11:52 +03:00
|
|
|
#include "ruby/util.h"
|
2019-12-04 11:16:30 +03:00
|
|
|
#include "ruby_assert.h"
|
|
|
|
#include "vm_core.h"
|
2024-02-23 22:08:09 +03:00
|
|
|
#include "yjit.h"
|
2019-12-04 11:16:30 +03:00
|
|
|
|
|
|
|
#include "builtin.h"
|
|
|
|
|
2017-07-22 15:26:19 +03:00
|
|
|
/*!
|
2020-12-21 05:15:08 +03:00
|
|
|
* \addtogroup exception
|
2017-07-22 15:26:19 +03:00
|
|
|
* \{
|
|
|
|
*/
|
|
|
|
|
2004-07-16 06:17:59 +04:00
|
|
|
#ifndef EXIT_SUCCESS
|
|
|
|
#define EXIT_SUCCESS 0
|
|
|
|
#endif
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2010-12-20 18:40:07 +03:00
|
|
|
#ifndef WIFEXITED
|
|
|
|
#define WIFEXITED(status) 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef WEXITSTATUS
|
|
|
|
#define WEXITSTATUS(status) (status)
|
|
|
|
#endif
|
|
|
|
|
2015-12-08 08:27:10 +03:00
|
|
|
VALUE rb_iseqw_local_variables(VALUE iseqval);
|
|
|
|
VALUE rb_iseqw_new(const rb_iseq_t *);
|
2017-01-19 09:25:06 +03:00
|
|
|
int rb_str_end_with_asciichar(VALUE str, int c);
|
2015-12-08 08:27:10 +03:00
|
|
|
|
2020-05-14 19:22:56 +03:00
|
|
|
long rb_backtrace_length_limit = -1;
|
2013-04-08 23:58:55 +04:00
|
|
|
VALUE rb_eEAGAIN;
|
|
|
|
VALUE rb_eEWOULDBLOCK;
|
|
|
|
VALUE rb_eEINPROGRESS;
|
ruby/ruby.h: remove unnecessary exports from C-API
Needlessly exporting can reduce performance locally and increase
binary size.
Increasing the footprint of our C-API larger is also detrimental
to our development as it encourages tighter coupling with our
internals; making it harder for us to preserve compatibility.
If some parts of the core codebase needs access to globals,
internal.h should be used instead of anything in include/ruby/*.
"Urabe, Shyouhei" <shyouhei@ruby-lang.org> wrote:
> On Thu, Jan 18, 2018 at 7:33 PM, Eric Wong <normalperson@yhbt.net> wrote:
> > shyouhei@ruby-lang.org wrote:
> >> https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=61908
> >>
> >> export rb_mFConst
> >
> > Why are we exporting all these and making the public C-API bigger?
> > If anything, we should make these static. Thanks.
>
> No concrete reason, except they have already been externed in 2.5.
> These variables had lacked declarations so far, which resulted in their
> visibility to be that of extern. The commit is just confirming the status quo.
>
> I'm not against to turn them into static.
This reverts changes from r61910, r61909, r61908, r61907, and r61906.
* transcode.c (rb_eUndefinedConversionError): make static
(rb_eInvalidByteSequenceError): ditto
(rb_eConverterNotFoundError): ditto
* process.c (rb_mProcGID, rb_mProcUid, rb_mProcID_Syscall): ditto
* file.c (rb_mFConst): ditto
* error.c (rb_mWarning, rb_cWarningBuffer): ditto
* enumerator.c (rb_cLazy): ditto
[Misc #14381]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62029 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-25 00:07:14 +03:00
|
|
|
static VALUE rb_mWarning;
|
|
|
|
static VALUE rb_cWarningBuffer;
|
2016-09-27 12:19:14 +03:00
|
|
|
|
|
|
|
static ID id_warn;
|
2020-09-03 01:49:40 +03:00
|
|
|
static ID id_category;
|
2020-12-15 09:15:23 +03:00
|
|
|
static ID id_deprecated;
|
|
|
|
static ID id_experimental;
|
2023-04-13 13:11:14 +03:00
|
|
|
static ID id_performance;
|
2024-11-05 21:41:59 +03:00
|
|
|
static ID id_strict_unused_block;
|
Add rb_category_warn{,ing} for warning messages with categories
This adds the following C-API functions that can be used to emit
warnings with categories included:
```c
void rb_category_warn(const char *, const char*, ...)
void rb_category_warning(const char*, const char*, ...)
```
Internally in error.c, there is an rb_warn_category function
that will call Warning.warn with the string and the category
keyword if it doesn't have an arity of 1, and will call
Warning.warn with just the string if it has an arity of 1.
This refactors the rb_warn_deprecated{,_to_remove} functions
to use rb_warn_category.
This makes Kernel#warn accept a category keyword and pass it
to Warning.warn, so that Ruby methods can more easily emit
warnings with categories. rb_warn_category makes sure that
the passed category is a already defined category symbol
before calling Warning.warn.
The only currently defined warning category is :deprecated,
since that is what is already used. More categories can be
added in later commits.
2020-09-03 18:00:10 +03:00
|
|
|
static VALUE sym_category;
|
2022-02-07 10:05:45 +03:00
|
|
|
static VALUE sym_highlight;
|
2020-12-24 04:27:59 +03:00
|
|
|
static struct {
|
|
|
|
st_table *id2enum, *enum2id;
|
|
|
|
} warning_categories;
|
2013-04-08 23:58:55 +04:00
|
|
|
|
2022-06-14 18:08:36 +03:00
|
|
|
extern const char *rb_dynamic_description;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2009-11-24 14:03:51 +03:00
|
|
|
static const char *
|
|
|
|
rb_strerrno(int err)
|
|
|
|
{
|
2010-12-12 05:54:23 +03:00
|
|
|
#define defined_error(name, num) if (err == (num)) return (name);
|
2010-05-29 22:51:39 +04:00
|
|
|
#define undefined_error(name)
|
2009-11-24 14:03:51 +03:00
|
|
|
#include "known_errors.inc"
|
|
|
|
#undef defined_error
|
|
|
|
#undef undefined_error
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2003-06-02 08:49:46 +04:00
|
|
|
static int
|
* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,
eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
ruby_nerrs): purge global variables.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-05 12:12:18 +04:00
|
|
|
err_position_0(char *buf, long len, const char *file, int line)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2007-05-02 01:45:48 +04:00
|
|
|
if (!file) {
|
2003-06-02 08:49:46 +04:00
|
|
|
return 0;
|
1999-10-16 14:33:06 +04:00
|
|
|
}
|
2007-05-02 01:45:48 +04:00
|
|
|
else if (line == 0) {
|
|
|
|
return snprintf(buf, len, "%s: ", file);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
else {
|
2007-05-02 01:45:48 +04:00
|
|
|
return snprintf(buf, len, "%s:%d: ", file, line);
|
1999-10-16 14:33:06 +04:00
|
|
|
}
|
2003-06-02 08:49:46 +04:00
|
|
|
}
|
|
|
|
|
2021-09-09 08:05:11 +03:00
|
|
|
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 5, 0)
|
2012-12-22 18:59:21 +04:00
|
|
|
static VALUE
|
2016-04-19 11:42:50 +03:00
|
|
|
err_vcatf(VALUE str, const char *pre, const char *file, int line,
|
|
|
|
const char *fmt, va_list args)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2012-12-22 18:59:21 +04:00
|
|
|
if (file) {
|
|
|
|
rb_str_cat2(str, file);
|
|
|
|
if (line) rb_str_catf(str, ":%d", line);
|
|
|
|
rb_str_cat2(str, ": ");
|
2007-05-02 01:45:48 +04:00
|
|
|
}
|
2012-12-22 18:59:21 +04:00
|
|
|
if (pre) rb_str_cat2(str, pre);
|
|
|
|
rb_str_vcatf(str, fmt, args);
|
|
|
|
return str;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2022-11-20 16:59:52 +03:00
|
|
|
static VALUE syntax_error_with_path(VALUE, VALUE, VALUE*, rb_encoding*);
|
|
|
|
|
2016-03-19 08:46:20 +03:00
|
|
|
VALUE
|
2016-04-19 11:42:50 +03:00
|
|
|
rb_syntax_error_append(VALUE exc, VALUE file, int line, int column,
|
|
|
|
rb_encoding *enc, const char *fmt, va_list args)
|
2012-06-21 02:25:46 +04:00
|
|
|
{
|
2016-04-19 11:42:50 +03:00
|
|
|
const char *fn = NIL_P(file) ? NULL : RSTRING_PTR(file);
|
|
|
|
if (!exc) {
|
|
|
|
VALUE mesg = rb_enc_str_new(0, 0, enc);
|
|
|
|
err_vcatf(mesg, NULL, fn, line, fmt, args);
|
2012-12-22 18:59:21 +04:00
|
|
|
rb_str_cat2(mesg, "\n");
|
2012-12-25 08:38:18 +04:00
|
|
|
rb_write_error_str(mesg);
|
2012-06-21 02:25:46 +04:00
|
|
|
}
|
2016-03-19 08:46:20 +03:00
|
|
|
else {
|
2016-04-20 04:25:55 +03:00
|
|
|
VALUE mesg;
|
2022-11-20 16:59:52 +03:00
|
|
|
exc = syntax_error_with_path(exc, file, &mesg, enc);
|
2016-08-12 06:50:33 +03:00
|
|
|
err_vcatf(mesg, NULL, fn, line, fmt, args);
|
2016-03-19 08:46:20 +03:00
|
|
|
}
|
2012-06-21 02:25:46 +04:00
|
|
|
|
2016-04-19 11:42:50 +03:00
|
|
|
return exc;
|
2012-06-21 02:25:46 +04:00
|
|
|
}
|
2010-12-28 12:43:49 +03:00
|
|
|
|
2020-08-31 08:58:31 +03:00
|
|
|
static unsigned int warning_disabled_categories = (
|
2023-04-13 09:43:34 +03:00
|
|
|
(1U << RB_WARN_CATEGORY_DEPRECATED) |
|
2023-04-13 17:48:59 +03:00
|
|
|
~RB_WARN_CATEGORY_DEFAULT_BITS);
|
2019-11-12 12:34:49 +03:00
|
|
|
|
|
|
|
static unsigned int
|
|
|
|
rb_warning_category_mask(VALUE category)
|
|
|
|
{
|
2019-12-17 08:52:15 +03:00
|
|
|
return 1U << rb_warning_category_from_name(category);
|
|
|
|
}
|
|
|
|
|
|
|
|
rb_warning_category_t
|
|
|
|
rb_warning_category_from_name(VALUE category)
|
|
|
|
{
|
2020-12-24 04:27:59 +03:00
|
|
|
st_data_t cat_value;
|
|
|
|
ID cat_id;
|
2019-11-12 12:34:49 +03:00
|
|
|
Check_Type(category, T_SYMBOL);
|
2020-12-24 04:27:59 +03:00
|
|
|
if (!(cat_id = rb_check_id(&category)) ||
|
|
|
|
!st_lookup(warning_categories.id2enum, cat_id, &cat_value)) {
|
2019-11-12 12:34:49 +03:00
|
|
|
rb_raise(rb_eArgError, "unknown category: %"PRIsVALUE, category);
|
|
|
|
}
|
2020-12-24 04:27:59 +03:00
|
|
|
return (rb_warning_category_t)cat_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_warning_category_to_name(rb_warning_category_t category)
|
|
|
|
{
|
|
|
|
st_data_t id;
|
|
|
|
if (!st_lookup(warning_categories.enum2id, category, &id)) {
|
|
|
|
rb_raise(rb_eArgError, "invalid category: %d", (int)category);
|
|
|
|
}
|
|
|
|
return id ? ID2SYM(id) : Qnil;
|
2019-11-12 12:34:49 +03:00
|
|
|
}
|
|
|
|
|
2019-12-20 17:05:22 +03:00
|
|
|
void
|
|
|
|
rb_warning_category_update(unsigned int mask, unsigned int bits)
|
|
|
|
{
|
|
|
|
warning_disabled_categories &= ~mask;
|
|
|
|
warning_disabled_categories |= mask & ~bits;
|
|
|
|
}
|
|
|
|
|
2023-03-07 08:34:31 +03:00
|
|
|
bool
|
2019-12-17 08:52:15 +03:00
|
|
|
rb_warning_category_enabled_p(rb_warning_category_t category)
|
2019-11-12 12:34:49 +03:00
|
|
|
{
|
2019-12-17 08:52:15 +03:00
|
|
|
return !(warning_disabled_categories & (1U << category));
|
2019-11-12 12:34:49 +03:00
|
|
|
}
|
|
|
|
|
2019-12-22 09:18:22 +03:00
|
|
|
/*
|
2020-12-08 11:49:51 +03:00
|
|
|
* call-seq:
|
2019-12-22 09:18:22 +03:00
|
|
|
* Warning[category] -> true or false
|
|
|
|
*
|
|
|
|
* Returns the flag to show the warning messages for +category+.
|
|
|
|
* Supported categories are:
|
|
|
|
*
|
2023-08-01 08:54:16 +03:00
|
|
|
* +:deprecated+ ::
|
|
|
|
* deprecation warnings
|
|
|
|
* * assignment of non-nil value to <code>$,</code> and <code>$;</code>
|
|
|
|
* * keyword arguments
|
|
|
|
* etc.
|
2019-12-22 09:18:22 +03:00
|
|
|
*
|
2023-08-01 08:54:16 +03:00
|
|
|
* +:experimental+ ::
|
|
|
|
* experimental features
|
|
|
|
*
|
|
|
|
* +:performance+ ::
|
|
|
|
* performance hints
|
|
|
|
* * Shape variation limit
|
2019-12-22 09:18:22 +03:00
|
|
|
*/
|
|
|
|
|
2019-11-12 12:34:49 +03:00
|
|
|
static VALUE
|
|
|
|
rb_warning_s_aref(VALUE mod, VALUE category)
|
|
|
|
{
|
2019-12-17 08:52:15 +03:00
|
|
|
rb_warning_category_t cat = rb_warning_category_from_name(category);
|
2021-08-02 06:06:44 +03:00
|
|
|
return RBOOL(rb_warning_category_enabled_p(cat));
|
2019-11-12 12:34:49 +03:00
|
|
|
}
|
|
|
|
|
2019-12-22 09:18:22 +03:00
|
|
|
/*
|
2020-12-08 11:49:51 +03:00
|
|
|
* call-seq:
|
2019-12-22 09:18:22 +03:00
|
|
|
* Warning[category] = flag -> flag
|
|
|
|
*
|
|
|
|
* Sets the warning flags for +category+.
|
|
|
|
* See Warning.[] for the categories.
|
|
|
|
*/
|
|
|
|
|
2019-11-12 12:34:49 +03:00
|
|
|
static VALUE
|
|
|
|
rb_warning_s_aset(VALUE mod, VALUE category, VALUE flag)
|
|
|
|
{
|
|
|
|
unsigned int mask = rb_warning_category_mask(category);
|
|
|
|
unsigned int disabled = warning_disabled_categories;
|
|
|
|
if (!RTEST(flag))
|
|
|
|
disabled |= mask;
|
|
|
|
else
|
|
|
|
disabled &= ~mask;
|
|
|
|
warning_disabled_categories = disabled;
|
|
|
|
return flag;
|
|
|
|
}
|
|
|
|
|
2024-02-22 16:25:12 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* categories -> array
|
|
|
|
*
|
|
|
|
* Returns a list of the supported category symbols.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_warning_s_categories(VALUE mod)
|
|
|
|
{
|
|
|
|
st_index_t num = warning_categories.id2enum->num_entries;
|
|
|
|
ID *ids = ALLOCA_N(ID, num);
|
|
|
|
num = st_keys(warning_categories.id2enum, ids, num);
|
|
|
|
VALUE ary = rb_ary_new_capa(num);
|
|
|
|
for (st_index_t i = 0; i < num; ++i) {
|
|
|
|
rb_ary_push(ary, ID2SYM(ids[i]));
|
|
|
|
}
|
|
|
|
return rb_ary_freeze(ary);
|
|
|
|
}
|
|
|
|
|
2017-04-25 12:10:46 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2020-09-03 01:49:40 +03:00
|
|
|
* warn(msg, category: nil) -> nil
|
2017-04-25 12:10:46 +03:00
|
|
|
*
|
2018-12-05 04:19:23 +03:00
|
|
|
* Writes warning message +msg+ to $stderr. This method is called by
|
2020-08-06 20:25:11 +03:00
|
|
|
* Ruby for all emitted warnings. A +category+ may be included with
|
2020-12-08 13:33:43 +03:00
|
|
|
* the warning.
|
2020-10-02 13:02:54 +03:00
|
|
|
*
|
|
|
|
* See the documentation of the Warning module for how to customize this.
|
2017-04-25 12:10:46 +03:00
|
|
|
*/
|
|
|
|
|
2016-09-27 12:19:14 +03:00
|
|
|
static VALUE
|
2020-08-06 20:25:11 +03:00
|
|
|
rb_warning_s_warn(int argc, VALUE *argv, VALUE mod)
|
2016-09-27 12:19:14 +03:00
|
|
|
{
|
2020-08-06 20:25:11 +03:00
|
|
|
VALUE str;
|
|
|
|
VALUE opt;
|
2020-12-08 13:33:43 +03:00
|
|
|
VALUE category = Qnil;
|
2020-08-06 20:25:11 +03:00
|
|
|
|
|
|
|
rb_scan_args(argc, argv, "1:", &str, &opt);
|
2020-09-03 01:49:40 +03:00
|
|
|
if (!NIL_P(opt)) rb_get_kwargs(opt, &id_category, 0, 1, &category);
|
|
|
|
|
2016-09-27 18:21:01 +03:00
|
|
|
Check_Type(str, T_STRING);
|
|
|
|
rb_must_asciicompat(str);
|
2020-12-08 13:33:43 +03:00
|
|
|
if (!NIL_P(category)) {
|
|
|
|
rb_warning_category_t cat = rb_warning_category_from_name(category);
|
|
|
|
if (!rb_warning_category_enabled_p(cat)) return Qnil;
|
|
|
|
}
|
2016-09-27 12:19:14 +03:00
|
|
|
rb_write_error_str(str);
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
|
2017-04-25 12:10:46 +03:00
|
|
|
/*
|
|
|
|
* Document-module: Warning
|
|
|
|
*
|
|
|
|
* The Warning module contains a single method named #warn, and the
|
2019-03-22 14:04:59 +03:00
|
|
|
* module extends itself, making Warning.warn available.
|
2017-04-26 23:09:34 +03:00
|
|
|
* Warning.warn is called for all warnings issued by Ruby.
|
2017-04-25 12:10:46 +03:00
|
|
|
* By default, warnings are printed to $stderr.
|
|
|
|
*
|
2020-10-02 13:02:54 +03:00
|
|
|
* Changing the behavior of Warning.warn is useful to customize how warnings are
|
|
|
|
* handled by Ruby, for instance by filtering some warnings, and/or outputting
|
2023-12-09 07:54:33 +03:00
|
|
|
* warnings somewhere other than <tt>$stderr</tt>.
|
2020-10-02 13:02:54 +03:00
|
|
|
*
|
|
|
|
* If you want to change the behavior of Warning.warn you should use
|
2023-12-09 07:54:33 +03:00
|
|
|
* <tt>Warning.extend(MyNewModuleWithWarnMethod)</tt> and you can use +super+
|
|
|
|
* to get the default behavior of printing the warning to <tt>$stderr</tt>.
|
2020-10-02 13:02:54 +03:00
|
|
|
*
|
|
|
|
* Example:
|
|
|
|
* module MyWarningFilter
|
2020-10-03 14:19:24 +03:00
|
|
|
* def warn(message, category: nil, **kwargs)
|
2021-03-02 20:33:20 +03:00
|
|
|
* if /some warning I want to ignore/.match?(message)
|
2020-10-02 13:02:54 +03:00
|
|
|
* # ignore
|
|
|
|
* else
|
2020-10-03 14:19:24 +03:00
|
|
|
* super
|
2020-10-02 13:02:54 +03:00
|
|
|
* end
|
|
|
|
* end
|
|
|
|
* end
|
|
|
|
* Warning.extend MyWarningFilter
|
|
|
|
*
|
|
|
|
* You should never redefine Warning#warn (the instance method), as that will
|
|
|
|
* then no longer provide a way to use the default behavior.
|
|
|
|
*
|
2023-12-09 07:54:33 +03:00
|
|
|
* The warning[https://rubygems.org/gems/warning] gem provides convenient ways to customize Warning.warn.
|
2017-04-25 12:10:46 +03:00
|
|
|
*/
|
|
|
|
|
2019-11-18 06:13:08 +03:00
|
|
|
static VALUE
|
2017-04-25 11:17:24 +03:00
|
|
|
rb_warning_warn(VALUE mod, VALUE str)
|
|
|
|
{
|
|
|
|
return rb_funcallv(mod, id_warn, 1, &str);
|
|
|
|
}
|
|
|
|
|
Add rb_category_warn{,ing} for warning messages with categories
This adds the following C-API functions that can be used to emit
warnings with categories included:
```c
void rb_category_warn(const char *, const char*, ...)
void rb_category_warning(const char*, const char*, ...)
```
Internally in error.c, there is an rb_warn_category function
that will call Warning.warn with the string and the category
keyword if it doesn't have an arity of 1, and will call
Warning.warn with just the string if it has an arity of 1.
This refactors the rb_warn_deprecated{,_to_remove} functions
to use rb_warn_category.
This makes Kernel#warn accept a category keyword and pass it
to Warning.warn, so that Ruby methods can more easily emit
warnings with categories. rb_warn_category makes sure that
the passed category is a already defined category symbol
before calling Warning.warn.
The only currently defined warning category is :deprecated,
since that is what is already used. More categories can be
added in later commits.
2020-09-03 18:00:10 +03:00
|
|
|
|
|
|
|
static int
|
2020-12-08 13:33:43 +03:00
|
|
|
rb_warning_warn_arity(void)
|
|
|
|
{
|
2022-01-04 20:13:19 +03:00
|
|
|
const rb_method_entry_t *me = rb_method_entry(rb_singleton_class(rb_mWarning), id_warn);
|
|
|
|
return me ? rb_method_entry_arity(me) : 1;
|
Add rb_category_warn{,ing} for warning messages with categories
This adds the following C-API functions that can be used to emit
warnings with categories included:
```c
void rb_category_warn(const char *, const char*, ...)
void rb_category_warning(const char*, const char*, ...)
```
Internally in error.c, there is an rb_warn_category function
that will call Warning.warn with the string and the category
keyword if it doesn't have an arity of 1, and will call
Warning.warn with just the string if it has an arity of 1.
This refactors the rb_warn_deprecated{,_to_remove} functions
to use rb_warn_category.
This makes Kernel#warn accept a category keyword and pass it
to Warning.warn, so that Ruby methods can more easily emit
warnings with categories. rb_warn_category makes sure that
the passed category is a already defined category symbol
before calling Warning.warn.
The only currently defined warning category is :deprecated,
since that is what is already used. More categories can be
added in later commits.
2020-09-03 18:00:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_warn_category(VALUE str, VALUE category)
|
|
|
|
{
|
2020-12-24 04:27:59 +03:00
|
|
|
if (RUBY_DEBUG && !NIL_P(category)) {
|
|
|
|
rb_warning_category_from_name(category);
|
Add rb_category_warn{,ing} for warning messages with categories
This adds the following C-API functions that can be used to emit
warnings with categories included:
```c
void rb_category_warn(const char *, const char*, ...)
void rb_category_warning(const char*, const char*, ...)
```
Internally in error.c, there is an rb_warn_category function
that will call Warning.warn with the string and the category
keyword if it doesn't have an arity of 1, and will call
Warning.warn with just the string if it has an arity of 1.
This refactors the rb_warn_deprecated{,_to_remove} functions
to use rb_warn_category.
This makes Kernel#warn accept a category keyword and pass it
to Warning.warn, so that Ruby methods can more easily emit
warnings with categories. rb_warn_category makes sure that
the passed category is a already defined category symbol
before calling Warning.warn.
The only currently defined warning category is :deprecated,
since that is what is already used. More categories can be
added in later commits.
2020-09-03 18:00:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (rb_warning_warn_arity() == 1) {
|
|
|
|
return rb_warning_warn(rb_mWarning, str);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
VALUE args[2];
|
|
|
|
args[0] = str;
|
|
|
|
args[1] = rb_hash_new();
|
|
|
|
rb_hash_aset(args[1], sym_category, category);
|
|
|
|
return rb_funcallv_kw(rb_mWarning, id_warn, 2, args, RB_PASS_KEYWORDS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-27 12:19:14 +03:00
|
|
|
static void
|
|
|
|
rb_write_warning_str(VALUE str)
|
|
|
|
{
|
2017-04-25 11:17:24 +03:00
|
|
|
rb_warning_warn(rb_mWarning, str);
|
2016-09-27 12:19:14 +03:00
|
|
|
}
|
|
|
|
|
2021-09-09 08:05:11 +03:00
|
|
|
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 4, 0)
|
2016-04-18 10:08:35 +03:00
|
|
|
static VALUE
|
|
|
|
warn_vsprintf(rb_encoding *enc, const char *file, int line, const char *fmt, va_list args)
|
2007-05-02 01:45:48 +04:00
|
|
|
{
|
2016-04-19 11:42:50 +03:00
|
|
|
VALUE str = rb_enc_str_new(0, 0, enc);
|
2007-05-02 01:45:48 +04:00
|
|
|
|
2016-04-19 11:42:50 +03:00
|
|
|
err_vcatf(str, "warning: ", file, line, fmt, args);
|
2016-04-18 10:08:35 +03:00
|
|
|
return rb_str_cat2(str, "\n");
|
2007-05-02 01:45:48 +04:00
|
|
|
}
|
|
|
|
|
2024-05-07 22:23:10 +03:00
|
|
|
#define with_warn_vsprintf(enc, file, line, fmt) \
|
2022-08-09 07:22:21 +03:00
|
|
|
VALUE str; \
|
|
|
|
va_list args; \
|
|
|
|
va_start(args, fmt); \
|
2024-05-07 22:23:10 +03:00
|
|
|
str = warn_vsprintf(enc, file, line, fmt, args); \
|
2022-08-09 07:22:21 +03:00
|
|
|
va_end(args);
|
|
|
|
|
2007-05-02 01:45:48 +04:00
|
|
|
void
|
* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,
eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
ruby_nerrs): purge global variables.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-05 12:12:18 +04:00
|
|
|
rb_compile_warn(const char *file, int line, const char *fmt, ...)
|
2007-05-02 01:45:48 +04:00
|
|
|
{
|
2022-08-09 07:22:21 +03:00
|
|
|
if (!NIL_P(ruby_verbose)) {
|
2024-05-07 22:23:10 +03:00
|
|
|
with_warn_vsprintf(NULL, file, line, fmt) {
|
|
|
|
rb_write_warning_str(str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
rb_enc_compile_warn(rb_encoding *enc, const char *file, int line, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
if (!NIL_P(ruby_verbose)) {
|
|
|
|
with_warn_vsprintf(enc, file, line, fmt) {
|
2022-08-09 07:22:21 +03:00
|
|
|
rb_write_warning_str(str);
|
|
|
|
}
|
|
|
|
}
|
2007-05-02 01:45:48 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* rb_compile_warning() reports only in verbose mode */
|
|
|
|
void
|
* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,
eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
ruby_nerrs): purge global variables.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-05 12:12:18 +04:00
|
|
|
rb_compile_warning(const char *file, int line, const char *fmt, ...)
|
2007-05-02 01:45:48 +04:00
|
|
|
{
|
2022-08-09 07:22:21 +03:00
|
|
|
if (RTEST(ruby_verbose)) {
|
2024-05-07 22:23:10 +03:00
|
|
|
with_warn_vsprintf(NULL, file, line, fmt) {
|
|
|
|
rb_write_warning_str(str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* rb_enc_compile_warning() reports only in verbose mode */
|
|
|
|
void
|
|
|
|
rb_enc_compile_warning(rb_encoding *enc, const char *file, int line, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
if (RTEST(ruby_verbose)) {
|
|
|
|
with_warn_vsprintf(enc, file, line, fmt) {
|
2022-08-09 07:22:21 +03:00
|
|
|
rb_write_warning_str(str);
|
|
|
|
}
|
|
|
|
}
|
2007-05-02 01:45:48 +04:00
|
|
|
}
|
|
|
|
|
2020-12-16 20:02:23 +03:00
|
|
|
void
|
|
|
|
rb_category_compile_warn(rb_warning_category_t category, const char *file, int line, const char *fmt, ...)
|
|
|
|
{
|
2022-08-09 07:22:21 +03:00
|
|
|
if (!NIL_P(ruby_verbose)) {
|
2024-05-07 22:23:10 +03:00
|
|
|
with_warn_vsprintf(NULL, file, line, fmt) {
|
2022-08-09 07:22:21 +03:00
|
|
|
rb_warn_category(str, rb_warning_category_to_name(category));
|
|
|
|
}
|
|
|
|
}
|
2020-12-16 20:02:23 +03:00
|
|
|
}
|
|
|
|
|
2021-09-09 08:05:11 +03:00
|
|
|
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 0)
|
2015-02-06 11:37:19 +03:00
|
|
|
static VALUE
|
|
|
|
warning_string(rb_encoding *enc, const char *fmt, va_list args)
|
2000-11-08 08:29:37 +03:00
|
|
|
{
|
2015-10-31 04:02:26 +03:00
|
|
|
int line;
|
2017-11-16 08:52:19 +03:00
|
|
|
const char *file = rb_source_location_cstr(&line);
|
2017-11-16 08:56:21 +03:00
|
|
|
return warn_vsprintf(enc, file, line, fmt, args);
|
2000-11-08 08:29:37 +03:00
|
|
|
}
|
|
|
|
|
2017-03-27 13:44:32 +03:00
|
|
|
#define with_warning_string(mesg, enc, fmt) \
|
2022-09-30 11:26:46 +03:00
|
|
|
with_warning_string_from(mesg, enc, fmt, fmt)
|
|
|
|
#define with_warning_string_from(mesg, enc, fmt, last_arg) \
|
2017-03-27 13:44:32 +03:00
|
|
|
VALUE mesg; \
|
2022-09-30 11:26:46 +03:00
|
|
|
va_list args; va_start(args, last_arg); \
|
2017-03-27 13:44:32 +03:00
|
|
|
mesg = warning_string(enc, fmt, args); \
|
|
|
|
va_end(args);
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
void
|
1999-08-13 09:45:20 +04:00
|
|
|
rb_warn(const char *fmt, ...)
|
1999-01-20 07:59:39 +03:00
|
|
|
{
|
2017-03-27 13:44:32 +03:00
|
|
|
if (!NIL_P(ruby_verbose)) {
|
|
|
|
with_warning_string(mesg, 0, fmt) {
|
|
|
|
rb_write_warning_str(mesg);
|
|
|
|
}
|
|
|
|
}
|
1999-01-20 07:59:39 +03:00
|
|
|
}
|
|
|
|
|
Add rb_category_warn{,ing} for warning messages with categories
This adds the following C-API functions that can be used to emit
warnings with categories included:
```c
void rb_category_warn(const char *, const char*, ...)
void rb_category_warning(const char*, const char*, ...)
```
Internally in error.c, there is an rb_warn_category function
that will call Warning.warn with the string and the category
keyword if it doesn't have an arity of 1, and will call
Warning.warn with just the string if it has an arity of 1.
This refactors the rb_warn_deprecated{,_to_remove} functions
to use rb_warn_category.
This makes Kernel#warn accept a category keyword and pass it
to Warning.warn, so that Ruby methods can more easily emit
warnings with categories. rb_warn_category makes sure that
the passed category is a already defined category symbol
before calling Warning.warn.
The only currently defined warning category is :deprecated,
since that is what is already used. More categories can be
added in later commits.
2020-09-03 18:00:10 +03:00
|
|
|
void
|
2020-12-16 19:15:13 +03:00
|
|
|
rb_category_warn(rb_warning_category_t category, const char *fmt, ...)
|
Add rb_category_warn{,ing} for warning messages with categories
This adds the following C-API functions that can be used to emit
warnings with categories included:
```c
void rb_category_warn(const char *, const char*, ...)
void rb_category_warning(const char*, const char*, ...)
```
Internally in error.c, there is an rb_warn_category function
that will call Warning.warn with the string and the category
keyword if it doesn't have an arity of 1, and will call
Warning.warn with just the string if it has an arity of 1.
This refactors the rb_warn_deprecated{,_to_remove} functions
to use rb_warn_category.
This makes Kernel#warn accept a category keyword and pass it
to Warning.warn, so that Ruby methods can more easily emit
warnings with categories. rb_warn_category makes sure that
the passed category is a already defined category symbol
before calling Warning.warn.
The only currently defined warning category is :deprecated,
since that is what is already used. More categories can be
added in later commits.
2020-09-03 18:00:10 +03:00
|
|
|
{
|
2024-06-11 02:05:03 +03:00
|
|
|
if (!NIL_P(ruby_verbose) && rb_warning_category_enabled_p(category)) {
|
Add rb_category_warn{,ing} for warning messages with categories
This adds the following C-API functions that can be used to emit
warnings with categories included:
```c
void rb_category_warn(const char *, const char*, ...)
void rb_category_warning(const char*, const char*, ...)
```
Internally in error.c, there is an rb_warn_category function
that will call Warning.warn with the string and the category
keyword if it doesn't have an arity of 1, and will call
Warning.warn with just the string if it has an arity of 1.
This refactors the rb_warn_deprecated{,_to_remove} functions
to use rb_warn_category.
This makes Kernel#warn accept a category keyword and pass it
to Warning.warn, so that Ruby methods can more easily emit
warnings with categories. rb_warn_category makes sure that
the passed category is a already defined category symbol
before calling Warning.warn.
The only currently defined warning category is :deprecated,
since that is what is already used. More categories can be
added in later commits.
2020-09-03 18:00:10 +03:00
|
|
|
with_warning_string(mesg, 0, fmt) {
|
2020-12-24 04:27:59 +03:00
|
|
|
rb_warn_category(mesg, rb_warning_category_to_name(category));
|
Add rb_category_warn{,ing} for warning messages with categories
This adds the following C-API functions that can be used to emit
warnings with categories included:
```c
void rb_category_warn(const char *, const char*, ...)
void rb_category_warning(const char*, const char*, ...)
```
Internally in error.c, there is an rb_warn_category function
that will call Warning.warn with the string and the category
keyword if it doesn't have an arity of 1, and will call
Warning.warn with just the string if it has an arity of 1.
This refactors the rb_warn_deprecated{,_to_remove} functions
to use rb_warn_category.
This makes Kernel#warn accept a category keyword and pass it
to Warning.warn, so that Ruby methods can more easily emit
warnings with categories. rb_warn_category makes sure that
the passed category is a already defined category symbol
before calling Warning.warn.
The only currently defined warning category is :deprecated,
since that is what is already used. More categories can be
added in later commits.
2020-09-03 18:00:10 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-06 11:37:24 +03:00
|
|
|
void
|
|
|
|
rb_enc_warn(rb_encoding *enc, const char *fmt, ...)
|
|
|
|
{
|
2017-03-27 13:44:32 +03:00
|
|
|
if (!NIL_P(ruby_verbose)) {
|
|
|
|
with_warning_string(mesg, enc, fmt) {
|
|
|
|
rb_write_warning_str(mesg);
|
|
|
|
}
|
|
|
|
}
|
2015-02-06 11:37:24 +03:00
|
|
|
}
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
/* rb_warning() reports only in verbose mode */
|
|
|
|
void
|
1999-08-13 09:45:20 +04:00
|
|
|
rb_warning(const char *fmt, ...)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2017-03-27 13:44:32 +03:00
|
|
|
if (RTEST(ruby_verbose)) {
|
|
|
|
with_warning_string(mesg, 0, fmt) {
|
|
|
|
rb_write_warning_str(mesg);
|
|
|
|
}
|
|
|
|
}
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
Add rb_category_warn{,ing} for warning messages with categories
This adds the following C-API functions that can be used to emit
warnings with categories included:
```c
void rb_category_warn(const char *, const char*, ...)
void rb_category_warning(const char*, const char*, ...)
```
Internally in error.c, there is an rb_warn_category function
that will call Warning.warn with the string and the category
keyword if it doesn't have an arity of 1, and will call
Warning.warn with just the string if it has an arity of 1.
This refactors the rb_warn_deprecated{,_to_remove} functions
to use rb_warn_category.
This makes Kernel#warn accept a category keyword and pass it
to Warning.warn, so that Ruby methods can more easily emit
warnings with categories. rb_warn_category makes sure that
the passed category is a already defined category symbol
before calling Warning.warn.
The only currently defined warning category is :deprecated,
since that is what is already used. More categories can be
added in later commits.
2020-09-03 18:00:10 +03:00
|
|
|
/* rb_category_warning() reports only in verbose mode */
|
|
|
|
void
|
2020-12-16 19:15:13 +03:00
|
|
|
rb_category_warning(rb_warning_category_t category, const char *fmt, ...)
|
Add rb_category_warn{,ing} for warning messages with categories
This adds the following C-API functions that can be used to emit
warnings with categories included:
```c
void rb_category_warn(const char *, const char*, ...)
void rb_category_warning(const char*, const char*, ...)
```
Internally in error.c, there is an rb_warn_category function
that will call Warning.warn with the string and the category
keyword if it doesn't have an arity of 1, and will call
Warning.warn with just the string if it has an arity of 1.
This refactors the rb_warn_deprecated{,_to_remove} functions
to use rb_warn_category.
This makes Kernel#warn accept a category keyword and pass it
to Warning.warn, so that Ruby methods can more easily emit
warnings with categories. rb_warn_category makes sure that
the passed category is a already defined category symbol
before calling Warning.warn.
The only currently defined warning category is :deprecated,
since that is what is already used. More categories can be
added in later commits.
2020-09-03 18:00:10 +03:00
|
|
|
{
|
2024-06-11 02:05:03 +03:00
|
|
|
if (RTEST(ruby_verbose) && rb_warning_category_enabled_p(category)) {
|
Add rb_category_warn{,ing} for warning messages with categories
This adds the following C-API functions that can be used to emit
warnings with categories included:
```c
void rb_category_warn(const char *, const char*, ...)
void rb_category_warning(const char*, const char*, ...)
```
Internally in error.c, there is an rb_warn_category function
that will call Warning.warn with the string and the category
keyword if it doesn't have an arity of 1, and will call
Warning.warn with just the string if it has an arity of 1.
This refactors the rb_warn_deprecated{,_to_remove} functions
to use rb_warn_category.
This makes Kernel#warn accept a category keyword and pass it
to Warning.warn, so that Ruby methods can more easily emit
warnings with categories. rb_warn_category makes sure that
the passed category is a already defined category symbol
before calling Warning.warn.
The only currently defined warning category is :deprecated,
since that is what is already used. More categories can be
added in later commits.
2020-09-03 18:00:10 +03:00
|
|
|
with_warning_string(mesg, 0, fmt) {
|
2020-12-24 04:27:59 +03:00
|
|
|
rb_warn_category(mesg, rb_warning_category_to_name(category));
|
Add rb_category_warn{,ing} for warning messages with categories
This adds the following C-API functions that can be used to emit
warnings with categories included:
```c
void rb_category_warn(const char *, const char*, ...)
void rb_category_warning(const char*, const char*, ...)
```
Internally in error.c, there is an rb_warn_category function
that will call Warning.warn with the string and the category
keyword if it doesn't have an arity of 1, and will call
Warning.warn with just the string if it has an arity of 1.
This refactors the rb_warn_deprecated{,_to_remove} functions
to use rb_warn_category.
This makes Kernel#warn accept a category keyword and pass it
to Warning.warn, so that Ruby methods can more easily emit
warnings with categories. rb_warn_category makes sure that
the passed category is a already defined category symbol
before calling Warning.warn.
The only currently defined warning category is :deprecated,
since that is what is already used. More categories can be
added in later commits.
2020-09-03 18:00:10 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-27 15:07:43 +03:00
|
|
|
VALUE
|
|
|
|
rb_warning_string(const char *fmt, ...)
|
|
|
|
{
|
|
|
|
with_warning_string(mesg, 0, fmt) {
|
|
|
|
}
|
|
|
|
return mesg;
|
|
|
|
}
|
|
|
|
|
2015-02-06 11:37:24 +03:00
|
|
|
#if 0
|
|
|
|
void
|
|
|
|
rb_enc_warning(rb_encoding *enc, const char *fmt, ...)
|
|
|
|
{
|
2017-03-27 13:44:32 +03:00
|
|
|
if (RTEST(ruby_verbose)) {
|
|
|
|
with_warning_string(mesg, enc, fmt) {
|
|
|
|
rb_write_warning_str(mesg);
|
|
|
|
}
|
|
|
|
}
|
2015-02-06 11:37:24 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-12-22 10:37:35 +03:00
|
|
|
static bool
|
|
|
|
deprecation_warning_enabled(void)
|
|
|
|
{
|
|
|
|
if (NIL_P(ruby_verbose)) return false;
|
|
|
|
if (!rb_warning_category_enabled_p(RB_WARN_CATEGORY_DEPRECATED)) return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-12-28 13:17:52 +03:00
|
|
|
warn_deprecated(VALUE mesg, const char *removal, const char *suggest)
|
2020-12-22 10:37:35 +03:00
|
|
|
{
|
|
|
|
rb_str_set_len(mesg, RSTRING_LEN(mesg) - 1);
|
|
|
|
rb_str_cat_cstr(mesg, " is deprecated");
|
2020-12-28 13:17:52 +03:00
|
|
|
if (removal) {
|
|
|
|
rb_str_catf(mesg, " and will be removed in Ruby %s", removal);
|
|
|
|
}
|
2020-12-22 10:37:35 +03:00
|
|
|
if (suggest) rb_str_catf(mesg, "; use %s instead", suggest);
|
|
|
|
rb_str_cat_cstr(mesg, "\n");
|
|
|
|
rb_warn_category(mesg, ID2SYM(id_deprecated));
|
|
|
|
}
|
|
|
|
|
2019-12-17 11:17:07 +03:00
|
|
|
void
|
|
|
|
rb_warn_deprecated(const char *fmt, const char *suggest, ...)
|
|
|
|
{
|
2020-12-22 10:37:35 +03:00
|
|
|
if (!deprecation_warning_enabled()) return;
|
|
|
|
|
2022-10-10 07:52:25 +03:00
|
|
|
with_warning_string_from(mesg, 0, fmt, suggest) {
|
|
|
|
warn_deprecated(mesg, NULL, suggest);
|
|
|
|
}
|
2019-12-17 11:17:07 +03:00
|
|
|
}
|
|
|
|
|
2020-01-23 15:42:05 +03:00
|
|
|
void
|
2020-12-28 13:17:52 +03:00
|
|
|
rb_warn_deprecated_to_remove(const char *removal, const char *fmt, const char *suggest, ...)
|
2020-01-23 15:42:05 +03:00
|
|
|
{
|
2020-12-22 10:37:35 +03:00
|
|
|
if (!deprecation_warning_enabled()) return;
|
|
|
|
|
2022-10-10 07:52:25 +03:00
|
|
|
with_warning_string_from(mesg, 0, fmt, suggest) {
|
|
|
|
warn_deprecated(mesg, removal, suggest);
|
|
|
|
}
|
2020-01-23 15:42:05 +03:00
|
|
|
}
|
|
|
|
|
2017-04-26 23:13:07 +03:00
|
|
|
static inline int
|
|
|
|
end_with_asciichar(VALUE str, int c)
|
|
|
|
{
|
|
|
|
return RB_TYPE_P(str, T_STRING) &&
|
|
|
|
rb_str_end_with_asciichar(str, c);
|
|
|
|
}
|
|
|
|
|
2018-02-23 05:16:42 +03:00
|
|
|
/* :nodoc: */
|
2017-10-23 09:42:37 +03:00
|
|
|
static VALUE
|
|
|
|
warning_write(int argc, VALUE *argv, VALUE buf)
|
|
|
|
{
|
|
|
|
while (argc-- > 0) {
|
|
|
|
rb_str_append(buf, *argv++);
|
|
|
|
}
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
2020-10-11 14:36:25 +03:00
|
|
|
VALUE rb_ec_backtrace_location_ary(const rb_execution_context_t *ec, long lev, long n, bool skip_internal);
|
|
|
|
|
2003-06-02 08:49:46 +04:00
|
|
|
static VALUE
|
Add rb_category_warn{,ing} for warning messages with categories
This adds the following C-API functions that can be used to emit
warnings with categories included:
```c
void rb_category_warn(const char *, const char*, ...)
void rb_category_warning(const char*, const char*, ...)
```
Internally in error.c, there is an rb_warn_category function
that will call Warning.warn with the string and the category
keyword if it doesn't have an arity of 1, and will call
Warning.warn with just the string if it has an arity of 1.
This refactors the rb_warn_deprecated{,_to_remove} functions
to use rb_warn_category.
This makes Kernel#warn accept a category keyword and pass it
to Warning.warn, so that Ruby methods can more easily emit
warnings with categories. rb_warn_category makes sure that
the passed category is a already defined category symbol
before calling Warning.warn.
The only currently defined warning category is :deprecated,
since that is what is already used. More categories can be
added in later commits.
2020-09-03 18:00:10 +03:00
|
|
|
rb_warn_m(rb_execution_context_t *ec, VALUE exc, VALUE msgs, VALUE uplevel, VALUE category)
|
2019-12-10 14:22:42 +03:00
|
|
|
{
|
|
|
|
VALUE location = Qnil;
|
|
|
|
int argc = RARRAY_LENINT(msgs);
|
|
|
|
const VALUE *argv = RARRAY_CONST_PTR(msgs);
|
|
|
|
|
|
|
|
if (!NIL_P(ruby_verbose) && argc > 0) {
|
|
|
|
VALUE str = argv[0];
|
|
|
|
if (!NIL_P(uplevel)) {
|
|
|
|
long lev = NUM2LONG(uplevel);
|
|
|
|
if (lev < 0) {
|
|
|
|
rb_raise(rb_eArgError, "negative level (%ld)", lev);
|
|
|
|
}
|
2020-10-11 14:36:25 +03:00
|
|
|
location = rb_ec_backtrace_location_ary(ec, lev + 1, 1, TRUE);
|
2019-12-10 14:22:42 +03:00
|
|
|
if (!NIL_P(location)) {
|
|
|
|
location = rb_ary_entry(location, 0);
|
|
|
|
}
|
2017-12-12 14:56:25 +03:00
|
|
|
}
|
|
|
|
if (argc > 1 || !NIL_P(uplevel) || !end_with_asciichar(str, '\n')) {
|
2018-04-02 14:39:10 +03:00
|
|
|
VALUE path;
|
2017-12-12 14:56:25 +03:00
|
|
|
if (NIL_P(uplevel)) {
|
|
|
|
str = rb_str_tmp_new(0);
|
|
|
|
}
|
2018-04-02 14:39:10 +03:00
|
|
|
else if (NIL_P(location) ||
|
|
|
|
NIL_P(path = rb_funcall(location, rb_intern("path"), 0))) {
|
|
|
|
str = rb_str_new_cstr("warning: ");
|
|
|
|
}
|
2017-12-12 14:56:25 +03:00
|
|
|
else {
|
2017-12-31 16:15:52 +03:00
|
|
|
str = rb_sprintf("%s:%ld: warning: ",
|
2017-12-12 14:56:25 +03:00
|
|
|
rb_string_value_ptr(&path),
|
2018-04-02 14:39:10 +03:00
|
|
|
NUM2LONG(rb_funcall(location, rb_intern("lineno"), 0)));
|
2017-12-12 14:56:25 +03:00
|
|
|
}
|
2017-04-26 23:13:07 +03:00
|
|
|
RBASIC_SET_CLASS(str, rb_cWarningBuffer);
|
|
|
|
rb_io_puts(argc, argv, str);
|
|
|
|
RBASIC_SET_CLASS(str, rb_cString);
|
|
|
|
}
|
Add rb_category_warn{,ing} for warning messages with categories
This adds the following C-API functions that can be used to emit
warnings with categories included:
```c
void rb_category_warn(const char *, const char*, ...)
void rb_category_warning(const char*, const char*, ...)
```
Internally in error.c, there is an rb_warn_category function
that will call Warning.warn with the string and the category
keyword if it doesn't have an arity of 1, and will call
Warning.warn with just the string if it has an arity of 1.
This refactors the rb_warn_deprecated{,_to_remove} functions
to use rb_warn_category.
This makes Kernel#warn accept a category keyword and pass it
to Warning.warn, so that Ruby methods can more easily emit
warnings with categories. rb_warn_category makes sure that
the passed category is a already defined category symbol
before calling Warning.warn.
The only currently defined warning category is :deprecated,
since that is what is already used. More categories can be
added in later commits.
2020-09-03 18:00:10 +03:00
|
|
|
|
2020-12-24 04:27:59 +03:00
|
|
|
if (!NIL_P(category)) {
|
|
|
|
category = rb_to_symbol_type(category);
|
|
|
|
rb_warning_category_from_name(category);
|
|
|
|
}
|
|
|
|
|
2017-10-13 04:34:52 +03:00
|
|
|
if (exc == rb_mWarning) {
|
|
|
|
rb_must_asciicompat(str);
|
|
|
|
rb_write_error_str(str);
|
|
|
|
}
|
|
|
|
else {
|
Add rb_category_warn{,ing} for warning messages with categories
This adds the following C-API functions that can be used to emit
warnings with categories included:
```c
void rb_category_warn(const char *, const char*, ...)
void rb_category_warning(const char*, const char*, ...)
```
Internally in error.c, there is an rb_warn_category function
that will call Warning.warn with the string and the category
keyword if it doesn't have an arity of 1, and will call
Warning.warn with just the string if it has an arity of 1.
This refactors the rb_warn_deprecated{,_to_remove} functions
to use rb_warn_category.
This makes Kernel#warn accept a category keyword and pass it
to Warning.warn, so that Ruby methods can more easily emit
warnings with categories. rb_warn_category makes sure that
the passed category is a already defined category symbol
before calling Warning.warn.
The only currently defined warning category is :deprecated,
since that is what is already used. More categories can be
added in later commits.
2020-09-03 18:00:10 +03:00
|
|
|
rb_warn_category(str, category);
|
2017-10-13 04:34:52 +03:00
|
|
|
}
|
2003-10-02 12:25:00 +04:00
|
|
|
}
|
|
|
|
return Qnil;
|
2003-06-02 08:49:46 +04:00
|
|
|
}
|
|
|
|
|
2013-10-16 12:39:39 +04:00
|
|
|
#define MAX_BUG_REPORTERS 0x100
|
|
|
|
|
|
|
|
static struct bug_reporters {
|
|
|
|
void (*func)(FILE *out, void *data);
|
|
|
|
void *data;
|
|
|
|
} bug_reporters[MAX_BUG_REPORTERS];
|
|
|
|
|
|
|
|
static int bug_reporters_size;
|
|
|
|
|
|
|
|
int
|
|
|
|
rb_bug_reporter_add(void (*func)(FILE *, void *), void *data)
|
|
|
|
{
|
|
|
|
struct bug_reporters *reporter;
|
|
|
|
if (bug_reporters_size >= MAX_BUG_REPORTERS) {
|
2013-10-17 00:32:28 +04:00
|
|
|
return 0; /* failed to register */
|
2013-10-16 12:39:39 +04:00
|
|
|
}
|
|
|
|
reporter = &bug_reporters[bug_reporters_size++];
|
|
|
|
reporter->func = func;
|
|
|
|
reporter->data = data;
|
|
|
|
|
2013-10-17 00:32:28 +04:00
|
|
|
return 1;
|
2013-10-16 12:39:39 +04:00
|
|
|
}
|
|
|
|
|
2023-07-31 22:12:22 +03:00
|
|
|
/* returns true if x can not be used as file name */
|
|
|
|
static bool
|
|
|
|
path_sep_p(char x)
|
|
|
|
{
|
|
|
|
#if defined __CYGWIN__ || defined DOSISH
|
|
|
|
# define PATH_SEP_ENCODING 1
|
|
|
|
// Assume that "/" is only the first byte in any encoding.
|
|
|
|
if (x == ':') return true; // drive letter or ADS
|
|
|
|
if (x == '\\') return true;
|
|
|
|
#endif
|
|
|
|
return x == '/';
|
|
|
|
}
|
|
|
|
|
|
|
|
struct path_string {
|
|
|
|
const char *ptr;
|
|
|
|
size_t len;
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char PATHSEP_REPLACE = '!';
|
|
|
|
|
|
|
|
static char *
|
|
|
|
append_pathname(char *p, const char *pe, VALUE str)
|
|
|
|
{
|
|
|
|
#ifdef PATH_SEP_ENCODING
|
|
|
|
rb_encoding *enc = rb_enc_get(str);
|
|
|
|
#endif
|
|
|
|
const char *s = RSTRING_PTR(str);
|
|
|
|
const char *const se = s + RSTRING_LEN(str);
|
|
|
|
char c;
|
|
|
|
|
|
|
|
--pe; // for terminator
|
|
|
|
|
|
|
|
while (p < pe && s < se && (c = *s) != '\0') {
|
|
|
|
if (c == '.') {
|
|
|
|
if (s == se || !*s) break; // chomp "." basename
|
|
|
|
if (path_sep_p(s[1])) goto skipsep; // skip "./"
|
|
|
|
}
|
|
|
|
else if (path_sep_p(c)) {
|
|
|
|
// squeeze successive separators
|
|
|
|
*p++ = PATHSEP_REPLACE;
|
|
|
|
skipsep:
|
|
|
|
while (++s < se && path_sep_p(*s));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
const char *const ss = s;
|
|
|
|
while (p < pe && s < se && *s && !path_sep_p(*s)) {
|
|
|
|
#ifdef PATH_SEP_ENCODING
|
|
|
|
int n = rb_enc_mbclen(s, se, enc);
|
|
|
|
#else
|
|
|
|
const int n = 1;
|
|
|
|
#endif
|
|
|
|
p += n;
|
|
|
|
s += n;
|
|
|
|
}
|
|
|
|
if (s > ss) memcpy(p - (s - ss), ss, s - ss);
|
|
|
|
}
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
append_basename(char *p, const char *pe, struct path_string *path, VALUE str)
|
|
|
|
{
|
|
|
|
if (!path->ptr) {
|
|
|
|
#ifdef PATH_SEP_ENCODING
|
|
|
|
rb_encoding *enc = rb_enc_get(str);
|
|
|
|
#endif
|
|
|
|
const char *const b = RSTRING_PTR(str), *const e = RSTRING_END(str), *p = e;
|
|
|
|
|
|
|
|
while (p > b) {
|
|
|
|
if (path_sep_p(p[-1])) {
|
|
|
|
#ifdef PATH_SEP_ENCODING
|
|
|
|
const char *t = rb_enc_prev_char(b, p, e, enc);
|
|
|
|
if (t == p-1) break;
|
|
|
|
p = t;
|
|
|
|
#else
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
--p;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
path->ptr = p;
|
|
|
|
path->len = e - p;
|
|
|
|
}
|
|
|
|
size_t n = path->len;
|
|
|
|
if (p + n > pe) n = pe - p;
|
|
|
|
memcpy(p, path->ptr, n);
|
|
|
|
return p + n;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2023-08-05 16:11:52 +03:00
|
|
|
finish_report(FILE *out, rb_pid_t pid)
|
2023-07-31 22:12:22 +03:00
|
|
|
{
|
|
|
|
if (out != stdout && out != stderr) fclose(out);
|
2023-08-05 16:11:52 +03:00
|
|
|
#ifdef HAVE_WORKING_FORK
|
|
|
|
if (pid > 0) waitpid(pid, NULL, 0);
|
|
|
|
#endif
|
2023-07-31 22:12:22 +03:00
|
|
|
}
|
|
|
|
|
2023-08-05 13:56:29 +03:00
|
|
|
struct report_expansion {
|
|
|
|
struct path_string exe, script;
|
|
|
|
rb_pid_t pid;
|
|
|
|
time_t time;
|
|
|
|
};
|
|
|
|
|
2023-07-31 22:12:22 +03:00
|
|
|
/*
|
2023-09-13 09:02:10 +03:00
|
|
|
* Open a bug report file to write. The `RUBY_CRASH_REPORT`
|
2023-07-31 22:12:22 +03:00
|
|
|
* environment variable can be set to define a template that is used
|
|
|
|
* to name bug report files. The template can contain % specifiers
|
|
|
|
* which are substituted by the following values when a bug report
|
|
|
|
* file is created:
|
|
|
|
*
|
|
|
|
* %% A single % character.
|
|
|
|
* %e The base name of the executable filename.
|
|
|
|
* %E Pathname of executable, with slashes ('/') replaced by
|
|
|
|
* exclamation marks ('!').
|
|
|
|
* %f Similar to %e with the main script filename.
|
|
|
|
* %F Similar to %E with the main script filename.
|
|
|
|
* %p PID of dumped process in decimal.
|
|
|
|
* %t Time of dump, expressed as seconds since the Epoch,
|
|
|
|
* 1970-01-01 00:00:00 +0000 (UTC).
|
2023-08-05 16:11:52 +03:00
|
|
|
* %NNN Octal char code, upto 3 digits.
|
2023-07-31 22:12:22 +03:00
|
|
|
*/
|
2023-08-05 13:56:29 +03:00
|
|
|
static char *
|
|
|
|
expand_report_argument(const char **input_template, struct report_expansion *values,
|
2023-08-05 16:11:52 +03:00
|
|
|
char *buf, size_t size, bool word)
|
2023-08-05 13:56:29 +03:00
|
|
|
{
|
|
|
|
char *p = buf;
|
|
|
|
char *end = buf + size;
|
|
|
|
const char *template = *input_template;
|
2023-08-05 16:11:52 +03:00
|
|
|
bool store = true;
|
2023-08-05 13:56:29 +03:00
|
|
|
|
|
|
|
if (p >= end-1 || !*template) return NULL;
|
|
|
|
do {
|
|
|
|
char c = *template++;
|
2023-08-05 16:11:52 +03:00
|
|
|
if (word && ISSPACE(c)) break;
|
|
|
|
if (!store) continue;
|
2023-08-05 13:56:29 +03:00
|
|
|
if (c == '%') {
|
2023-08-05 16:11:52 +03:00
|
|
|
size_t n;
|
2023-08-05 13:56:29 +03:00
|
|
|
switch (c = *template++) {
|
|
|
|
case 'e':
|
|
|
|
p = append_basename(p, end, &values->exe, rb_argv0);
|
|
|
|
continue;
|
|
|
|
case 'E':
|
|
|
|
p = append_pathname(p, end, rb_argv0);
|
|
|
|
continue;
|
|
|
|
case 'f':
|
|
|
|
p = append_basename(p, end, &values->script, GET_VM()->orig_progname);
|
|
|
|
continue;
|
|
|
|
case 'F':
|
|
|
|
p = append_pathname(p, end, GET_VM()->orig_progname);
|
|
|
|
continue;
|
|
|
|
case 'p':
|
|
|
|
if (!values->pid) values->pid = getpid();
|
|
|
|
snprintf(p, end-p, "%" PRI_PIDT_PREFIX "d", values->pid);
|
|
|
|
p += strlen(p);
|
|
|
|
continue;
|
|
|
|
case 't':
|
|
|
|
if (!values->time) values->time = time(NULL);
|
|
|
|
snprintf(p, end-p, "%" PRI_TIMET_PREFIX "d", values->time);
|
|
|
|
p += strlen(p);
|
|
|
|
continue;
|
2023-08-05 16:11:52 +03:00
|
|
|
default:
|
|
|
|
if (c >= '0' && c <= '7') {
|
|
|
|
c = (unsigned char)ruby_scan_oct(template-1, 3, &n);
|
|
|
|
template += n - 1;
|
|
|
|
if (!c) store = false;
|
|
|
|
}
|
|
|
|
break;
|
2023-08-05 13:56:29 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (p < end-1) *p++ = c;
|
|
|
|
} while (*template);
|
|
|
|
*input_template = template;
|
|
|
|
*p = '\0';
|
|
|
|
return ++p;
|
|
|
|
}
|
|
|
|
|
2023-08-05 16:11:52 +03:00
|
|
|
FILE *ruby_popen_writer(char *const *argv, rb_pid_t *pid);
|
|
|
|
|
2023-07-31 22:12:22 +03:00
|
|
|
static FILE *
|
2023-08-05 16:11:52 +03:00
|
|
|
open_report_path(const char *template, char *buf, size_t size, rb_pid_t *pid)
|
2023-07-31 22:12:22 +03:00
|
|
|
{
|
2023-08-05 13:56:29 +03:00
|
|
|
struct report_expansion values = {{0}};
|
|
|
|
|
|
|
|
if (!template) return NULL;
|
2023-09-13 09:02:10 +03:00
|
|
|
if (0) fprintf(stderr, "RUBY_CRASH_REPORT=%s\n", buf);
|
2023-08-05 16:11:52 +03:00
|
|
|
if (*template == '|') {
|
|
|
|
char *argv[16], *bufend = buf + size, *p;
|
|
|
|
int argc;
|
|
|
|
template++;
|
|
|
|
for (argc = 0; argc < numberof(argv) - 1; ++argc) {
|
|
|
|
while (*template && ISSPACE(*template)) template++;
|
|
|
|
p = expand_report_argument(&template, &values, buf, bufend-buf, true);
|
|
|
|
if (!p) break;
|
|
|
|
argv[argc] = buf;
|
|
|
|
buf = p;
|
|
|
|
}
|
|
|
|
argv[argc] = NULL;
|
|
|
|
if (!p) return ruby_popen_writer(argv, pid);
|
|
|
|
}
|
|
|
|
else if (*template) {
|
|
|
|
expand_report_argument(&template, &values, buf, size, false);
|
2023-07-31 22:12:22 +03:00
|
|
|
return fopen(buf, "w");
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2023-09-13 09:02:10 +03:00
|
|
|
static const char *crash_report;
|
2023-08-09 12:25:34 +03:00
|
|
|
|
2014-05-25 07:46:55 +04:00
|
|
|
/* SIGSEGV handler might have a very small stack. Thus we need to use it carefully. */
|
|
|
|
#define REPORT_BUG_BUFSIZ 256
|
|
|
|
static FILE *
|
2023-08-05 16:11:52 +03:00
|
|
|
bug_report_file(const char *file, int line, rb_pid_t *pid)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2014-05-25 07:46:55 +04:00
|
|
|
char buf[REPORT_BUG_BUFSIZ];
|
2023-09-13 09:02:10 +03:00
|
|
|
const char *report = crash_report;
|
|
|
|
if (!report) report = getenv("RUBY_CRASH_REPORT");
|
2023-08-09 12:25:34 +03:00
|
|
|
FILE *out = open_report_path(report, buf, sizeof(buf), pid);
|
2014-05-25 07:46:55 +04:00
|
|
|
int len = err_position_0(buf, sizeof(buf), file, line);
|
2003-08-27 17:33:27 +04:00
|
|
|
|
2023-07-31 22:12:22 +03:00
|
|
|
if (out) {
|
|
|
|
if ((ssize_t)fwrite(buf, 1, len, out) == (ssize_t)len) return out;
|
|
|
|
fclose(out);
|
|
|
|
}
|
|
|
|
if ((ssize_t)fwrite(buf, 1, len, stderr) == (ssize_t)len) {
|
|
|
|
return stderr;
|
|
|
|
}
|
|
|
|
if ((ssize_t)fwrite(buf, 1, len, stdout) == (ssize_t)len) {
|
|
|
|
return stdout;
|
2014-05-25 07:46:55 +04:00
|
|
|
}
|
2019-08-15 07:48:58 +03:00
|
|
|
|
2014-05-25 07:46:55 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-01-13 05:57:45 +03:00
|
|
|
FUNC_MINIMIZED(static void bug_important_message(FILE *out, const char *const msg, size_t len));
|
|
|
|
|
|
|
|
static void
|
|
|
|
bug_important_message(FILE *out, const char *const msg, size_t len)
|
|
|
|
{
|
|
|
|
const char *const endmsg = msg + len;
|
|
|
|
const char *p = msg;
|
|
|
|
|
|
|
|
if (!len) return;
|
|
|
|
if (isatty(fileno(out))) {
|
|
|
|
static const char red[] = "\033[;31;1;7m";
|
|
|
|
static const char green[] = "\033[;32;7m";
|
|
|
|
static const char reset[] = "\033[m";
|
|
|
|
const char *e = strchr(p, '\n');
|
|
|
|
const int w = (int)(e - p);
|
|
|
|
do {
|
|
|
|
int i = (int)(e - p);
|
|
|
|
fputs(*p == ' ' ? green : red, out);
|
|
|
|
fwrite(p, 1, e - p, out);
|
|
|
|
for (; i < w; ++i) fputc(' ', out);
|
|
|
|
fputs(reset, out);
|
|
|
|
fputc('\n', out);
|
|
|
|
} while ((p = e + 1) < endmsg && (e = strchr(p, '\n')) != 0 && e > p + 1);
|
|
|
|
}
|
|
|
|
fwrite(p, 1, endmsg - p, out);
|
|
|
|
}
|
|
|
|
|
2022-10-17 08:46:10 +03:00
|
|
|
#undef CRASH_REPORTER_MAY_BE_CREATED
|
|
|
|
#if defined(__APPLE__) && \
|
2022-10-19 13:49:45 +03:00
|
|
|
(!defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6 || defined(__POWERPC__)) /* 10.6 PPC case */
|
2022-10-17 08:46:10 +03:00
|
|
|
# define CRASH_REPORTER_MAY_BE_CREATED
|
|
|
|
#endif
|
2017-01-13 05:57:45 +03:00
|
|
|
static void
|
|
|
|
preface_dump(FILE *out)
|
|
|
|
{
|
|
|
|
#if defined __APPLE__
|
|
|
|
static const char msg[] = ""
|
|
|
|
"-- Crash Report log information "
|
|
|
|
"--------------------------------------------\n"
|
2021-02-06 17:05:37 +03:00
|
|
|
" See Crash Report log file in one of the following locations:\n"
|
2022-10-17 08:46:10 +03:00
|
|
|
# ifdef CRASH_REPORTER_MAY_BE_CREATED
|
2017-01-13 05:57:45 +03:00
|
|
|
" * ~/Library/Logs/CrashReporter\n"
|
|
|
|
" * /Library/Logs/CrashReporter\n"
|
2017-01-13 06:24:22 +03:00
|
|
|
# endif
|
2017-01-13 05:57:45 +03:00
|
|
|
" * ~/Library/Logs/DiagnosticReports\n"
|
|
|
|
" * /Library/Logs/DiagnosticReports\n"
|
|
|
|
" for more details.\n"
|
|
|
|
"Don't forget to include the above Crash Report log file in bug reports.\n"
|
|
|
|
"\n";
|
|
|
|
const size_t msglen = sizeof(msg) - 1;
|
|
|
|
#else
|
|
|
|
const char *msg = NULL;
|
|
|
|
const size_t msglen = 0;
|
|
|
|
#endif
|
|
|
|
bug_important_message(out, msg, msglen);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
postscript_dump(FILE *out)
|
|
|
|
{
|
|
|
|
#if defined __APPLE__
|
|
|
|
static const char msg[] = ""
|
2017-01-13 06:24:22 +03:00
|
|
|
"[IMPORTANT]"
|
|
|
|
/*" ------------------------------------------------"*/
|
|
|
|
"\n""Don't forget to include the Crash Report log file under\n"
|
2022-10-17 08:46:10 +03:00
|
|
|
# ifdef CRASH_REPORTER_MAY_BE_CREATED
|
2017-01-13 06:24:22 +03:00
|
|
|
"CrashReporter or "
|
|
|
|
# endif
|
|
|
|
"DiagnosticReports directory in bug reports.\n"
|
|
|
|
/*"------------------------------------------------------------\n"*/
|
2017-01-13 05:57:45 +03:00
|
|
|
"\n";
|
|
|
|
const size_t msglen = sizeof(msg) - 1;
|
|
|
|
#else
|
|
|
|
const char *msg = NULL;
|
|
|
|
const size_t msglen = 0;
|
|
|
|
#endif
|
|
|
|
bug_important_message(out, msg, msglen);
|
|
|
|
}
|
|
|
|
|
2021-09-09 08:05:11 +03:00
|
|
|
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 0)
|
2014-05-25 07:46:55 +04:00
|
|
|
static void
|
2016-04-19 07:46:20 +03:00
|
|
|
bug_report_begin_valist(FILE *out, const char *fmt, va_list args)
|
2014-05-25 07:46:55 +04:00
|
|
|
{
|
|
|
|
char buf[REPORT_BUG_BUFSIZ];
|
|
|
|
|
|
|
|
fputs("[BUG] ", out);
|
|
|
|
vsnprintf(buf, sizeof(buf), fmt, args);
|
|
|
|
fputs(buf, out);
|
2022-06-14 18:08:36 +03:00
|
|
|
snprintf(buf, sizeof(buf), "\n%s\n\n", rb_dynamic_description);
|
2014-05-25 07:46:55 +04:00
|
|
|
fputs(buf, out);
|
2017-01-13 05:57:45 +03:00
|
|
|
preface_dump(out);
|
2014-05-25 07:46:55 +04:00
|
|
|
}
|
2008-12-24 16:39:16 +03:00
|
|
|
|
2014-05-25 07:46:55 +04:00
|
|
|
#define bug_report_begin(out, fmt) do { \
|
|
|
|
va_list args; \
|
|
|
|
va_start(args, fmt); \
|
2016-04-19 07:46:20 +03:00
|
|
|
bug_report_begin_valist(out, fmt, args); \
|
2014-05-25 07:46:55 +04:00
|
|
|
va_end(args); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
static void
|
2023-08-05 16:11:52 +03:00
|
|
|
bug_report_end(FILE *out, rb_pid_t pid)
|
2014-05-25 07:46:55 +04:00
|
|
|
{
|
|
|
|
/* call additional bug reporters */
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i=0; i<bug_reporters_size; i++) {
|
|
|
|
struct bug_reporters *reporter = &bug_reporters[i];
|
|
|
|
(*reporter->func)(out, reporter->data);
|
2013-10-16 12:39:39 +04:00
|
|
|
}
|
2003-08-27 17:33:27 +04:00
|
|
|
}
|
2017-01-13 05:57:45 +03:00
|
|
|
postscript_dump(out);
|
2023-08-05 16:11:52 +03:00
|
|
|
finish_report(out, pid);
|
2014-05-25 07:46:55 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
#define report_bug(file, line, fmt, ctx) do { \
|
2023-08-05 16:11:52 +03:00
|
|
|
rb_pid_t pid = -1; \
|
|
|
|
FILE *out = bug_report_file(file, line, &pid); \
|
2014-05-25 07:46:55 +04:00
|
|
|
if (out) { \
|
|
|
|
bug_report_begin(out, fmt); \
|
2023-07-31 21:04:42 +03:00
|
|
|
rb_vm_bugreport(ctx, out); \
|
2023-08-05 16:11:52 +03:00
|
|
|
bug_report_end(out, pid); \
|
2014-05-25 07:46:55 +04:00
|
|
|
} \
|
|
|
|
} while (0) \
|
|
|
|
|
2016-04-19 07:46:20 +03:00
|
|
|
#define report_bug_valist(file, line, fmt, ctx, args) do { \
|
2023-08-05 16:11:52 +03:00
|
|
|
rb_pid_t pid = -1; \
|
|
|
|
FILE *out = bug_report_file(file, line, &pid); \
|
2016-04-19 07:46:20 +03:00
|
|
|
if (out) { \
|
|
|
|
bug_report_begin_valist(out, fmt, args); \
|
2023-07-31 21:04:42 +03:00
|
|
|
rb_vm_bugreport(ctx, out); \
|
2023-08-05 16:11:52 +03:00
|
|
|
bug_report_end(out, pid); \
|
2016-04-19 07:46:20 +03:00
|
|
|
} \
|
|
|
|
} while (0) \
|
|
|
|
|
2023-08-04 10:56:55 +03:00
|
|
|
void
|
2023-09-13 09:02:10 +03:00
|
|
|
ruby_set_crash_report(const char *template)
|
2023-08-04 10:56:55 +03:00
|
|
|
{
|
2023-09-13 09:02:10 +03:00
|
|
|
crash_report = template;
|
2023-08-09 12:25:34 +03:00
|
|
|
#if RUBY_DEBUG
|
2023-08-05 16:12:04 +03:00
|
|
|
rb_pid_t pid = -1;
|
2023-08-04 10:56:55 +03:00
|
|
|
char buf[REPORT_BUG_BUFSIZ];
|
2023-08-05 16:12:04 +03:00
|
|
|
FILE *out = open_report_path(template, buf, sizeof(buf), &pid);
|
2023-08-04 10:56:55 +03:00
|
|
|
if (out) {
|
|
|
|
time_t t = time(NULL);
|
|
|
|
fprintf(out, "ruby_test_bug_report: %s", ctime(&t));
|
2023-08-05 16:12:04 +03:00
|
|
|
finish_report(out, pid);
|
2023-08-04 10:56:55 +03:00
|
|
|
}
|
2023-08-09 12:25:34 +03:00
|
|
|
#endif
|
2023-08-04 10:56:55 +03:00
|
|
|
}
|
|
|
|
|
2014-05-25 07:46:55 +04:00
|
|
|
NORETURN(static void die(void));
|
|
|
|
static void
|
|
|
|
die(void)
|
|
|
|
{
|
|
|
|
#if defined(_WIN32) && defined(RUBY_MSVCRT_VERSION) && RUBY_MSVCRT_VERSION >= 80
|
|
|
|
_set_abort_behavior( 0, _CALL_REPORTFAULT);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
abort();
|
* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,
eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
ruby_nerrs): purge global variables.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-05 12:12:18 +04:00
|
|
|
}
|
2017-10-27 18:13:59 +03:00
|
|
|
|
2021-09-09 08:05:11 +03:00
|
|
|
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 0)
|
* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,
eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
ruby_nerrs): purge global variables.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-05 12:12:18 +04:00
|
|
|
void
|
2021-02-01 04:16:14 +03:00
|
|
|
rb_bug_without_die(const char *fmt, va_list args)
|
* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,
eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
ruby_nerrs): purge global variables.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-05 12:12:18 +04:00
|
|
|
{
|
2011-07-08 10:53:33 +04:00
|
|
|
const char *file = NULL;
|
|
|
|
int line = 0;
|
|
|
|
|
2017-10-28 14:20:17 +03:00
|
|
|
if (GET_EC()) {
|
2020-11-27 07:08:20 +03:00
|
|
|
file = rb_source_location_cstr(&line);
|
2011-07-08 10:53:33 +04:00
|
|
|
}
|
* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,
eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
ruby_nerrs): purge global variables.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-05 12:12:18 +04:00
|
|
|
|
2021-02-01 04:16:14 +03:00
|
|
|
report_bug_valist(file, line, fmt, NULL, args);
|
2020-11-27 07:08:20 +03:00
|
|
|
}
|
* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,
eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
ruby_nerrs): purge global variables.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-05 12:12:18 +04:00
|
|
|
|
2020-11-27 07:08:20 +03:00
|
|
|
void
|
|
|
|
rb_bug(const char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
va_start(args, fmt);
|
|
|
|
rb_bug_without_die(fmt, args);
|
|
|
|
va_end(args);
|
2014-05-25 07:46:55 +04:00
|
|
|
die();
|
|
|
|
}
|
2010-05-27 19:53:42 +04:00
|
|
|
|
2014-05-25 07:46:55 +04:00
|
|
|
void
|
2019-10-09 17:39:58 +03:00
|
|
|
rb_bug_for_fatal_signal(ruby_sighandler_t default_sighandler, int sig, const void *ctx, const char *fmt, ...)
|
2014-05-25 07:46:55 +04:00
|
|
|
{
|
|
|
|
const char *file = NULL;
|
|
|
|
int line = 0;
|
|
|
|
|
2017-10-28 14:20:17 +03:00
|
|
|
if (GET_EC()) {
|
2017-11-16 08:52:19 +03:00
|
|
|
file = rb_source_location_cstr(&line);
|
2014-05-25 07:46:55 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
report_bug(file, line, fmt, ctx);
|
|
|
|
|
2019-10-09 17:13:59 +03:00
|
|
|
if (default_sighandler) default_sighandler(sig);
|
|
|
|
|
2023-12-15 19:08:34 +03:00
|
|
|
ruby_default_signal(sig);
|
2014-05-25 07:46:55 +04:00
|
|
|
die();
|
* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,
eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
ruby_nerrs): purge global variables.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-05 12:12:18 +04:00
|
|
|
}
|
|
|
|
|
2014-05-25 07:46:55 +04:00
|
|
|
|
2009-11-24 14:03:51 +03:00
|
|
|
void
|
|
|
|
rb_bug_errno(const char *mesg, int errno_arg)
|
|
|
|
{
|
|
|
|
if (errno_arg == 0)
|
|
|
|
rb_bug("%s: errno == 0 (NOERROR)", mesg);
|
|
|
|
else {
|
|
|
|
const char *errno_str = rb_strerrno(errno_arg);
|
|
|
|
if (errno_str)
|
|
|
|
rb_bug("%s: %s (%s)", mesg, strerror(errno_arg), errno_str);
|
|
|
|
else
|
|
|
|
rb_bug("%s: %s (%d)", mesg, strerror(errno_arg), errno_arg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-29 01:17:29 +04:00
|
|
|
/*
|
|
|
|
* this is safe to call inside signal handler and timer thread
|
|
|
|
* (which isn't a Ruby Thread object)
|
|
|
|
*/
|
2011-07-01 03:03:23 +04:00
|
|
|
#define write_or_abort(fd, str, len) (write((fd), (str), (len)) < 0 ? abort() : (void)0)
|
|
|
|
#define WRITE_CONST(fd,str) write_or_abort((fd),(str),sizeof(str) - 1)
|
2011-06-29 01:17:29 +04:00
|
|
|
|
2011-07-01 03:03:23 +04:00
|
|
|
void
|
|
|
|
rb_async_bug_errno(const char *mesg, int errno_arg)
|
2011-06-29 01:17:29 +04:00
|
|
|
{
|
|
|
|
WRITE_CONST(2, "[ASYNC BUG] ");
|
2011-07-01 03:03:23 +04:00
|
|
|
write_or_abort(2, mesg, strlen(mesg));
|
2011-06-29 01:17:29 +04:00
|
|
|
WRITE_CONST(2, "\n");
|
|
|
|
|
|
|
|
if (errno_arg == 0) {
|
|
|
|
WRITE_CONST(2, "errno == 0 (NOERROR)\n");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
const char *errno_str = rb_strerrno(errno_arg);
|
|
|
|
|
|
|
|
if (!errno_str)
|
|
|
|
errno_str = "undefined errno";
|
2011-07-01 03:03:23 +04:00
|
|
|
write_or_abort(2, errno_str, strlen(errno_str));
|
2011-06-29 01:17:29 +04:00
|
|
|
}
|
|
|
|
WRITE_CONST(2, "\n\n");
|
2022-06-14 18:08:36 +03:00
|
|
|
write_or_abort(2, rb_dynamic_description, strlen(rb_dynamic_description));
|
2011-06-29 01:17:29 +04:00
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
2015-12-24 11:25:44 +03:00
|
|
|
void
|
2016-04-19 07:46:20 +03:00
|
|
|
rb_report_bug_valist(VALUE file, int line, const char *fmt, va_list args)
|
2015-12-24 11:25:44 +03:00
|
|
|
{
|
2016-04-19 07:46:20 +03:00
|
|
|
report_bug_valist(RSTRING_PTR(file), line, fmt, NULL, args);
|
2015-12-24 11:25:44 +03:00
|
|
|
}
|
|
|
|
|
2023-03-07 08:34:31 +03:00
|
|
|
void
|
2016-01-22 11:33:55 +03:00
|
|
|
rb_assert_failure(const char *file, int line, const char *name, const char *expr)
|
2024-01-31 09:09:51 +03:00
|
|
|
{
|
|
|
|
rb_assert_failure_detail(file, line, name, expr, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
rb_assert_failure_detail(const char *file, int line, const char *name, const char *expr,
|
|
|
|
const char *fmt, ...)
|
2016-01-22 11:33:55 +03:00
|
|
|
{
|
2024-11-07 17:35:19 +03:00
|
|
|
rb_pid_t pid = -1;
|
|
|
|
FILE *out = bug_report_file(file, line, &pid);
|
|
|
|
if (out) {
|
|
|
|
fputs("Assertion Failed: ", out);
|
|
|
|
if (name) fprintf(out, "%s:", name);
|
|
|
|
fputs(expr, out);
|
|
|
|
|
|
|
|
if (fmt && *fmt) {
|
|
|
|
va_list args;
|
|
|
|
va_start(args, fmt);
|
|
|
|
fputs(": ", out);
|
|
|
|
vfprintf(out, fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
}
|
|
|
|
fprintf(out, "\n%s\n\n", rb_dynamic_description);
|
|
|
|
|
|
|
|
preface_dump(out);
|
|
|
|
rb_vm_bugreport(NULL, out);
|
|
|
|
bug_report_end(out, pid);
|
2024-01-31 09:09:51 +03:00
|
|
|
}
|
|
|
|
|
2016-01-22 11:33:55 +03:00
|
|
|
die();
|
|
|
|
}
|
|
|
|
|
2012-07-18 12:45:29 +04:00
|
|
|
static const char builtin_types[][10] = {
|
|
|
|
"", /* 0x00, */
|
|
|
|
"Object",
|
|
|
|
"Class",
|
|
|
|
"Module",
|
|
|
|
"Float",
|
|
|
|
"String",
|
|
|
|
"Regexp",
|
|
|
|
"Array",
|
|
|
|
"Hash",
|
|
|
|
"Struct",
|
2020-06-15 18:26:17 +03:00
|
|
|
"Integer",
|
2012-07-18 12:45:29 +04:00
|
|
|
"File",
|
|
|
|
"Data", /* internal use: wrapped C pointers */
|
|
|
|
"MatchData", /* data of $~ */
|
|
|
|
"Complex",
|
|
|
|
"Rational",
|
|
|
|
"", /* 0x10 */
|
|
|
|
"nil",
|
|
|
|
"true",
|
|
|
|
"false",
|
|
|
|
"Symbol", /* :symbol */
|
2020-06-15 18:26:17 +03:00
|
|
|
"Integer",
|
2015-03-30 09:24:40 +03:00
|
|
|
"undef", /* internal use: #undef; should not happen */
|
2012-07-18 12:45:29 +04:00
|
|
|
"", /* 0x17 */
|
|
|
|
"", /* 0x18 */
|
|
|
|
"", /* 0x19 */
|
2021-08-14 04:17:38 +03:00
|
|
|
"<Memo>", /* internal use: general memo */
|
|
|
|
"<Node>", /* internal use: syntax tree node */
|
|
|
|
"<iClass>", /* internal use: mixed-in module holder */
|
1998-01-16 15:13:05 +03:00
|
|
|
};
|
|
|
|
|
2012-06-29 06:26:46 +04:00
|
|
|
const char *
|
|
|
|
rb_builtin_type_name(int t)
|
|
|
|
{
|
2012-07-18 12:45:29 +04:00
|
|
|
const char *name;
|
2012-07-18 13:25:18 +04:00
|
|
|
if ((unsigned int)t >= numberof(builtin_types)) return 0;
|
2012-07-18 12:45:29 +04:00
|
|
|
name = builtin_types[t];
|
|
|
|
if (*name) return name;
|
2012-06-29 06:26:46 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-06-24 04:58:13 +03:00
|
|
|
static VALUE
|
|
|
|
displaying_class_of(VALUE x)
|
|
|
|
{
|
|
|
|
switch (x) {
|
|
|
|
case Qfalse: return rb_fstring_cstr("false");
|
|
|
|
case Qnil: return rb_fstring_cstr("nil");
|
|
|
|
case Qtrue: return rb_fstring_cstr("true");
|
|
|
|
default: return rb_obj_class(x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-28 05:40:46 +03:00
|
|
|
static const char *
|
|
|
|
builtin_class_name(VALUE x)
|
2011-12-15 09:33:34 +04:00
|
|
|
{
|
|
|
|
const char *etype;
|
|
|
|
|
|
|
|
if (NIL_P(x)) {
|
|
|
|
etype = "nil";
|
|
|
|
}
|
|
|
|
else if (FIXNUM_P(x)) {
|
2016-05-17 09:53:48 +03:00
|
|
|
etype = "Integer";
|
2011-12-15 09:33:34 +04:00
|
|
|
}
|
|
|
|
else if (SYMBOL_P(x)) {
|
|
|
|
etype = "Symbol";
|
|
|
|
}
|
2011-12-15 18:19:59 +04:00
|
|
|
else if (RB_TYPE_P(x, T_TRUE)) {
|
|
|
|
etype = "true";
|
|
|
|
}
|
|
|
|
else if (RB_TYPE_P(x, T_FALSE)) {
|
|
|
|
etype = "false";
|
2011-12-15 09:33:34 +04:00
|
|
|
}
|
|
|
|
else {
|
2015-09-28 05:40:46 +03:00
|
|
|
etype = NULL;
|
|
|
|
}
|
|
|
|
return etype;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
rb_builtin_class_name(VALUE x)
|
|
|
|
{
|
|
|
|
const char *etype = builtin_class_name(x);
|
|
|
|
|
|
|
|
if (!etype) {
|
2011-12-15 09:33:34 +04:00
|
|
|
etype = rb_obj_classname(x);
|
|
|
|
}
|
|
|
|
return etype;
|
|
|
|
}
|
|
|
|
|
2021-08-14 04:16:37 +03:00
|
|
|
COLDFUNC NORETURN(static void unexpected_type(VALUE, int, int));
|
2016-07-23 16:43:44 +03:00
|
|
|
#define UNDEF_LEAKED "undef leaked to the Ruby space"
|
|
|
|
|
|
|
|
static void
|
|
|
|
unexpected_type(VALUE x, int xt, int t)
|
|
|
|
{
|
|
|
|
const char *tname = rb_builtin_type_name(t);
|
|
|
|
VALUE mesg, exc = rb_eFatal;
|
|
|
|
|
|
|
|
if (tname) {
|
2020-06-24 04:58:13 +03:00
|
|
|
mesg = rb_sprintf("wrong argument type %"PRIsVALUE" (expected %s)",
|
|
|
|
displaying_class_of(x), tname);
|
2016-07-23 16:43:44 +03:00
|
|
|
exc = rb_eTypeError;
|
|
|
|
}
|
|
|
|
else if (xt > T_MASK && xt <= 0x3f) {
|
|
|
|
mesg = rb_sprintf("unknown type 0x%x (0x%x given, probably comes"
|
|
|
|
" from extension library for ruby 1.8)", t, xt);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mesg = rb_sprintf("unknown type 0x%x (0x%x given)", t, xt);
|
|
|
|
}
|
|
|
|
rb_exc_raise(rb_exc_new_str(exc, mesg));
|
|
|
|
}
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
void
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_check_type(VALUE x, int t)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2009-07-08 14:10:28 +04:00
|
|
|
int xt;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2022-11-15 07:24:08 +03:00
|
|
|
if (RB_UNLIKELY(UNDEF_P(x))) {
|
2016-07-23 16:43:44 +03:00
|
|
|
rb_bug(UNDEF_LEAKED);
|
2000-11-10 11:52:23 +03:00
|
|
|
}
|
|
|
|
|
2009-07-08 14:10:28 +04:00
|
|
|
xt = TYPE(x);
|
2021-08-14 08:07:40 +03:00
|
|
|
if (xt != t || (xt == T_DATA && rbimpl_rtypeddata_p(x))) {
|
2021-08-14 04:14:51 +03:00
|
|
|
/*
|
|
|
|
* Typed data is not simple `T_DATA`, but in a sense an
|
|
|
|
* extension of `struct RVALUE`, which are incompatible with
|
|
|
|
* each other except when inherited.
|
|
|
|
*
|
|
|
|
* So it is not enough to just check `T_DATA`, it must be
|
|
|
|
* identified by its `type` using `Check_TypedStruct` instead.
|
|
|
|
*/
|
2016-07-23 16:43:44 +03:00
|
|
|
unexpected_type(x, xt, t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
rb_unexpected_type(VALUE x, int t)
|
|
|
|
{
|
2022-11-15 07:24:08 +03:00
|
|
|
if (RB_UNLIKELY(UNDEF_P(x))) {
|
2016-07-23 16:43:44 +03:00
|
|
|
rb_bug(UNDEF_LEAKED);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2016-07-23 16:43:44 +03:00
|
|
|
|
|
|
|
unexpected_type(x, TYPE(x), t);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2010-07-18 11:31:54 +04:00
|
|
|
int
|
|
|
|
rb_typeddata_inherited_p(const rb_data_type_t *child, const rb_data_type_t *parent)
|
|
|
|
{
|
2014-12-24 06:16:31 +03:00
|
|
|
while (child) {
|
|
|
|
if (child == parent) return 1;
|
|
|
|
child = child->parent;
|
|
|
|
}
|
2010-07-18 11:31:54 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-07-07 11:54:28 +04:00
|
|
|
int
|
2009-07-08 00:28:27 +04:00
|
|
|
rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
|
2009-07-07 11:54:28 +04:00
|
|
|
{
|
2012-05-23 11:13:21 +04:00
|
|
|
if (!RB_TYPE_P(obj, T_DATA) ||
|
2014-12-24 06:16:31 +03:00
|
|
|
!RTYPEDDATA_P(obj) || !rb_typeddata_inherited_p(RTYPEDDATA_TYPE(obj), data_type)) {
|
2009-07-07 11:54:28 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-11-27 06:19:06 +03:00
|
|
|
#undef rb_typeddata_is_instance_of
|
|
|
|
int
|
|
|
|
rb_typeddata_is_instance_of(VALUE obj, const rb_data_type_t *data_type)
|
|
|
|
{
|
|
|
|
return rb_typeddata_is_instance_of_inline(obj, data_type);
|
|
|
|
}
|
|
|
|
|
2009-07-07 08:44:54 +04:00
|
|
|
void *
|
2009-07-08 00:28:27 +04:00
|
|
|
rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
|
2009-07-07 08:44:54 +04:00
|
|
|
{
|
2020-06-24 04:58:13 +03:00
|
|
|
VALUE actual;
|
2009-07-07 08:44:54 +04:00
|
|
|
|
2012-05-23 11:13:21 +04:00
|
|
|
if (!RB_TYPE_P(obj, T_DATA)) {
|
2020-06-24 04:58:13 +03:00
|
|
|
actual = displaying_class_of(obj);
|
2020-06-15 05:37:35 +03:00
|
|
|
}
|
|
|
|
else if (!RTYPEDDATA_P(obj)) {
|
2020-06-24 04:58:13 +03:00
|
|
|
actual = displaying_class_of(obj);
|
2009-07-07 08:44:54 +04:00
|
|
|
}
|
2014-12-24 06:16:31 +03:00
|
|
|
else if (!rb_typeddata_inherited_p(RTYPEDDATA_TYPE(obj), data_type)) {
|
2020-06-24 04:58:13 +03:00
|
|
|
const char *name = RTYPEDDATA_TYPE(obj)->wrap_struct_name;
|
|
|
|
actual = rb_str_new_cstr(name); /* or rb_fstring_cstr? not sure... */
|
2020-06-15 05:37:35 +03:00
|
|
|
}
|
|
|
|
else {
|
2023-03-04 00:05:01 +03:00
|
|
|
return RTYPEDDATA_GET_DATA(obj);
|
2009-07-07 08:44:54 +04:00
|
|
|
}
|
2020-06-15 05:37:35 +03:00
|
|
|
|
|
|
|
const char *expected = data_type->wrap_struct_name;
|
|
|
|
rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected %s)",
|
|
|
|
actual, expected);
|
2020-06-24 10:23:59 +03:00
|
|
|
UNREACHABLE_RETURN(NULL);
|
2009-07-07 08:44:54 +04:00
|
|
|
}
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
/* exception classes */
|
1999-01-20 07:59:39 +03:00
|
|
|
VALUE rb_eException;
|
1999-08-13 09:45:20 +04:00
|
|
|
VALUE rb_eSystemExit;
|
|
|
|
VALUE rb_eInterrupt;
|
|
|
|
VALUE rb_eSignal;
|
|
|
|
VALUE rb_eFatal;
|
1999-01-20 07:59:39 +03:00
|
|
|
VALUE rb_eStandardError;
|
|
|
|
VALUE rb_eRuntimeError;
|
2017-12-12 03:46:34 +03:00
|
|
|
VALUE rb_eFrozenError;
|
1999-01-20 07:59:39 +03:00
|
|
|
VALUE rb_eTypeError;
|
|
|
|
VALUE rb_eArgError;
|
|
|
|
VALUE rb_eIndexError;
|
2004-09-22 08:48:52 +04:00
|
|
|
VALUE rb_eKeyError;
|
2000-03-07 11:37:59 +03:00
|
|
|
VALUE rb_eRangeError;
|
2001-06-05 11:50:59 +04:00
|
|
|
VALUE rb_eNameError;
|
2008-09-26 07:53:11 +04:00
|
|
|
VALUE rb_eEncodingError;
|
2008-09-18 12:57:33 +04:00
|
|
|
VALUE rb_eEncCompatError;
|
2001-06-05 11:50:59 +04:00
|
|
|
VALUE rb_eNoMethodError;
|
1999-01-20 07:59:39 +03:00
|
|
|
VALUE rb_eSecurityError;
|
|
|
|
VALUE rb_eNotImpError;
|
1999-12-14 09:50:43 +03:00
|
|
|
VALUE rb_eNoMemError;
|
2006-07-20 21:36:36 +04:00
|
|
|
VALUE rb_cNameErrorMesg;
|
2019-04-17 09:48:03 +03:00
|
|
|
VALUE rb_eNoMatchingPatternError;
|
2021-08-15 03:38:24 +03:00
|
|
|
VALUE rb_eNoMatchingPatternKeyError;
|
1999-01-20 07:59:39 +03:00
|
|
|
|
2000-02-01 06:12:21 +03:00
|
|
|
VALUE rb_eScriptError;
|
|
|
|
VALUE rb_eSyntaxError;
|
|
|
|
VALUE rb_eLoadError;
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
VALUE rb_eSystemCallError;
|
|
|
|
VALUE rb_mErrno;
|
2008-04-26 12:35:23 +04:00
|
|
|
static VALUE rb_eNOERROR;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2018-05-15 10:45:24 +03:00
|
|
|
ID ruby_static_id_cause;
|
|
|
|
#define id_cause ruby_static_id_cause
|
2022-02-01 11:59:31 +03:00
|
|
|
static ID id_message, id_detailed_message, id_backtrace;
|
2021-08-15 03:38:24 +03:00
|
|
|
static ID id_key, id_matchee, id_args, id_Errno, id_errno, id_i_path;
|
2018-04-12 12:34:54 +03:00
|
|
|
static ID id_receiver, id_recv, id_iseq, id_local_variables;
|
2018-03-22 11:26:23 +03:00
|
|
|
static ID id_private_call_p, id_top, id_bottom;
|
2015-02-23 10:05:06 +03:00
|
|
|
#define id_bt idBt
|
|
|
|
#define id_bt_locations idBt_locations
|
2015-02-23 01:57:18 +03:00
|
|
|
#define id_mesg idMesg
|
2019-08-03 02:37:08 +03:00
|
|
|
#define id_name idName
|
2015-02-16 06:58:28 +03:00
|
|
|
|
2013-06-01 06:16:25 +04:00
|
|
|
#undef rb_exc_new_cstr
|
2009-06-01 05:41:43 +04:00
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_exc_new(VALUE etype, const char *ptr, long len)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2018-02-20 13:08:27 +03:00
|
|
|
VALUE mesg = rb_str_new(ptr, len);
|
|
|
|
return rb_class_new_instance(1, &mesg, etype);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
2013-06-01 06:16:25 +04:00
|
|
|
rb_exc_new_cstr(VALUE etype, const char *s)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
1999-01-20 07:59:39 +03:00
|
|
|
return rb_exc_new(etype, s, strlen(s));
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
2013-06-01 06:16:25 +04:00
|
|
|
rb_exc_new_str(VALUE etype, VALUE str)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2024-02-23 22:08:09 +03:00
|
|
|
rb_yjit_lazy_push_frame(GET_EC()->cfp->pc);
|
2001-05-02 08:22:21 +04:00
|
|
|
StringValue(str);
|
2018-02-20 13:08:27 +03:00
|
|
|
return rb_class_new_instance(1, &str, etype);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2018-04-12 06:48:48 +03:00
|
|
|
static VALUE
|
|
|
|
exc_init(VALUE exc, VALUE mesg)
|
|
|
|
{
|
|
|
|
rb_ivar_set(exc, id_mesg, mesg);
|
|
|
|
rb_ivar_set(exc, id_bt, Qnil);
|
|
|
|
|
|
|
|
return exc;
|
|
|
|
}
|
|
|
|
|
2003-12-21 10:28:54 +03:00
|
|
|
/*
|
2024-06-26 20:31:40 +03:00
|
|
|
* call-seq:
|
|
|
|
* Exception.new(message = nil) -> exception
|
|
|
|
*
|
|
|
|
* Returns a new exception object.
|
|
|
|
*
|
|
|
|
* The given +message+ should be
|
|
|
|
* a {string-convertible object}[rdoc-ref:implicit_conversion.rdoc@String-Convertible+Objects];
|
|
|
|
* see method #message;
|
|
|
|
* if not given, the message is the class name of the new instance
|
|
|
|
* (which may be the name of a subclass):
|
|
|
|
*
|
|
|
|
* Examples:
|
|
|
|
*
|
|
|
|
* Exception.new # => #<Exception: Exception>
|
|
|
|
* LoadError.new # => #<LoadError: LoadError> # Subclass of Exception.
|
|
|
|
* Exception.new('Boom') # => #<Exception: Boom>
|
2003-12-21 10:28:54 +03:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
exc_initialize(int argc, VALUE *argv, VALUE exc)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2003-08-14 21:20:14 +04:00
|
|
|
VALUE arg;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2018-12-06 10:49:24 +03:00
|
|
|
arg = (!rb_check_arity(argc, 0, 1) ? Qnil : argv[0]);
|
2018-04-12 06:48:48 +03:00
|
|
|
return exc_init(exc, arg);
|
1999-01-20 07:59:39 +03:00
|
|
|
}
|
|
|
|
|
2003-12-21 10:28:54 +03:00
|
|
|
/*
|
2003-12-30 19:38:32 +03:00
|
|
|
* Document-method: exception
|
|
|
|
*
|
2003-12-21 10:28:54 +03:00
|
|
|
* call-seq:
|
2024-06-26 20:31:40 +03:00
|
|
|
* exception(message = nil) -> self or new_exception
|
|
|
|
*
|
|
|
|
* Returns an exception object of the same class as +self+;
|
|
|
|
* useful for creating a similar exception, but with a different message.
|
|
|
|
*
|
|
|
|
* With +message+ +nil+, returns +self+:
|
|
|
|
*
|
|
|
|
* x0 = StandardError.new('Boom') # => #<StandardError: Boom>
|
|
|
|
* x1 = x0.exception # => #<StandardError: Boom>
|
|
|
|
* x0.__id__ == x1.__id__ # => true
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* With {string-convertible object}[rdoc-ref:implicit_conversion.rdoc@String-Convertible+Objects]
|
|
|
|
* +message+ (even the same as the original message),
|
|
|
|
* returns a new exception object whose class is the same as +self+,
|
|
|
|
* and whose message is the given +message+:
|
|
|
|
*
|
|
|
|
* x1 = x0.exception('Boom') # => #<StandardError: Boom>
|
|
|
|
* x0..equal?(x1) # => false
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-21 10:28:54 +03:00
|
|
|
*/
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
exc_exception(int argc, VALUE *argv, VALUE self)
|
1999-01-20 07:59:39 +03:00
|
|
|
{
|
2001-07-02 12:46:28 +04:00
|
|
|
VALUE exc;
|
1999-01-20 07:59:39 +03:00
|
|
|
|
2019-09-02 10:47:12 +03:00
|
|
|
argc = rb_check_arity(argc, 0, 1);
|
1999-08-13 09:45:20 +04:00
|
|
|
if (argc == 0) return self;
|
1999-01-20 07:59:39 +03:00
|
|
|
if (argc == 1 && self == argv[0]) return self;
|
2001-07-02 12:46:28 +04:00
|
|
|
exc = rb_obj_clone(self);
|
2019-09-02 10:47:12 +03:00
|
|
|
rb_ivar_set(exc, id_mesg, argv[0]);
|
1999-01-20 07:59:39 +03:00
|
|
|
return exc;
|
|
|
|
}
|
|
|
|
|
2003-12-21 10:28:54 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2024-06-26 20:31:40 +03:00
|
|
|
* to_s -> string
|
|
|
|
*
|
|
|
|
* Returns a string representation of +self+:
|
|
|
|
*
|
|
|
|
* x = RuntimeError.new('Boom')
|
|
|
|
* x.to_s # => "Boom"
|
|
|
|
* x = RuntimeError.new
|
|
|
|
* x.to_s # => "RuntimeError"
|
2003-12-21 10:28:54 +03:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
exc_to_s(VALUE exc)
|
1999-01-20 07:59:39 +03:00
|
|
|
{
|
2015-02-16 06:58:28 +03:00
|
|
|
VALUE mesg = rb_attr_get(exc, idMesg);
|
1999-01-20 07:59:39 +03:00
|
|
|
|
2004-01-19 12:19:31 +03:00
|
|
|
if (NIL_P(mesg)) return rb_class_name(CLASS_OF(exc));
|
2013-10-28 08:17:20 +04:00
|
|
|
return rb_String(mesg);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2017-12-12 15:10:21 +03:00
|
|
|
/* FIXME: Include eval_error.c */
|
2022-02-01 11:59:31 +03:00
|
|
|
void rb_error_write(VALUE errinfo, VALUE emesg, VALUE errat, VALUE str, VALUE opt, VALUE highlight, VALUE reverse);
|
2018-04-11 11:03:43 +03:00
|
|
|
|
|
|
|
VALUE
|
|
|
|
rb_get_message(VALUE exc)
|
|
|
|
{
|
|
|
|
VALUE e = rb_check_funcall(exc, id_message, 0, 0);
|
2022-11-15 07:24:08 +03:00
|
|
|
if (UNDEF_P(e)) return Qnil;
|
2018-04-11 11:03:43 +03:00
|
|
|
if (!RB_TYPE_P(e, T_STRING)) e = rb_check_string_type(e);
|
|
|
|
return e;
|
|
|
|
}
|
2017-12-12 15:10:21 +03:00
|
|
|
|
2022-02-01 11:59:31 +03:00
|
|
|
VALUE
|
|
|
|
rb_get_detailed_message(VALUE exc, VALUE opt)
|
|
|
|
{
|
|
|
|
VALUE e;
|
|
|
|
if (NIL_P(opt)) {
|
|
|
|
e = rb_check_funcall(exc, id_detailed_message, 0, 0);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
e = rb_check_funcall_kw(exc, id_detailed_message, 1, &opt, 1);
|
|
|
|
}
|
2022-11-15 07:24:08 +03:00
|
|
|
if (UNDEF_P(e)) return Qnil;
|
2022-02-01 11:59:31 +03:00
|
|
|
if (!RB_TYPE_P(e, T_STRING)) e = rb_check_string_type(e);
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
2017-12-12 14:47:16 +03:00
|
|
|
/*
|
2024-06-26 20:31:40 +03:00
|
|
|
* call-seq:
|
|
|
|
* Exception.to_tty? -> true or false
|
2017-12-12 14:47:16 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* Returns +true+ if exception messages will be sent to a terminal device.
|
2018-03-22 11:26:23 +03:00
|
|
|
*/
|
|
|
|
static VALUE
|
|
|
|
exc_s_to_tty_p(VALUE self)
|
|
|
|
{
|
2021-08-02 06:06:44 +03:00
|
|
|
return RBOOL(rb_stderr_tty_p());
|
2018-03-22 11:26:23 +03:00
|
|
|
}
|
|
|
|
|
2022-02-01 09:58:39 +03:00
|
|
|
static VALUE
|
2022-02-02 09:08:10 +03:00
|
|
|
check_highlight_keyword(VALUE opt, int auto_tty_detect)
|
2022-02-01 09:58:39 +03:00
|
|
|
{
|
|
|
|
VALUE highlight = Qnil;
|
|
|
|
|
|
|
|
if (!NIL_P(opt)) {
|
2022-05-21 16:58:45 +03:00
|
|
|
highlight = rb_hash_lookup(opt, sym_highlight);
|
2022-02-01 09:58:39 +03:00
|
|
|
|
|
|
|
switch (highlight) {
|
|
|
|
default:
|
2022-05-24 10:48:34 +03:00
|
|
|
rb_bool_expected(highlight, "highlight", TRUE);
|
2022-02-01 09:58:39 +03:00
|
|
|
UNREACHABLE;
|
|
|
|
case Qtrue: case Qfalse: case Qnil: break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NIL_P(highlight)) {
|
2022-06-05 08:21:01 +03:00
|
|
|
highlight = RBOOL(auto_tty_detect && rb_stderr_tty_p());
|
2022-02-01 09:58:39 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return highlight;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
check_order_keyword(VALUE opt)
|
|
|
|
{
|
|
|
|
VALUE order = Qnil;
|
|
|
|
|
|
|
|
if (!NIL_P(opt)) {
|
|
|
|
static VALUE kw_order;
|
|
|
|
if (!kw_order) kw_order = ID2SYM(rb_intern_const("order"));
|
|
|
|
|
2022-05-21 16:58:45 +03:00
|
|
|
order = rb_hash_lookup(opt, kw_order);
|
2022-02-01 09:58:39 +03:00
|
|
|
|
|
|
|
if (order != Qnil) {
|
|
|
|
ID id = rb_check_id(&order);
|
|
|
|
if (id == id_bottom) order = Qtrue;
|
|
|
|
else if (id == id_top) order = Qfalse;
|
|
|
|
else {
|
|
|
|
rb_raise(rb_eArgError, "expected :top or :bottom as "
|
|
|
|
"order: %+"PRIsVALUE, order);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NIL_P(order)) order = Qfalse;
|
|
|
|
|
|
|
|
return order;
|
|
|
|
}
|
|
|
|
|
2018-03-22 11:26:23 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2024-06-26 20:31:40 +03:00
|
|
|
* full_message(highlight: true, order: :top) -> string
|
|
|
|
*
|
|
|
|
* Returns an enhanced message string:
|
|
|
|
*
|
|
|
|
* - Includes the exception class name.
|
|
|
|
* - If the value of keyword +highlight+ is true (not +nil+ or +false+),
|
|
|
|
* includes bolding ANSI codes (see below) to enhance the appearance of the message.
|
|
|
|
* - Includes the {backtrace}[rdoc-ref:exceptions.md@Backtraces]:
|
|
|
|
*
|
|
|
|
* - If the value of keyword +order+ is +:top+ (the default),
|
|
|
|
* lists the error message and the innermost backtrace entry first.
|
|
|
|
* - If the value of keyword +order+ is +:bottom+,
|
|
|
|
* lists the error message the the innermost entry last.
|
|
|
|
*
|
|
|
|
* Example:
|
2018-03-22 11:26:23 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* def baz
|
|
|
|
* begin
|
|
|
|
* 1 / 0
|
|
|
|
* rescue => x
|
|
|
|
* pp x.message
|
|
|
|
* pp x.full_message(highlight: false).split("\n")
|
|
|
|
* pp x.full_message.split("\n")
|
|
|
|
* end
|
|
|
|
* end
|
|
|
|
* def bar; baz; end
|
|
|
|
* def foo; bar; end
|
|
|
|
* foo
|
2018-03-22 11:26:23 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* Output:
|
2018-03-22 11:26:23 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* "divided by 0"
|
|
|
|
* ["t.rb:3:in `/': divided by 0 (ZeroDivisionError)",
|
|
|
|
* "\tfrom t.rb:3:in `baz'",
|
|
|
|
* "\tfrom t.rb:10:in `bar'",
|
|
|
|
* "\tfrom t.rb:11:in `foo'",
|
|
|
|
* "\tfrom t.rb:12:in `<main>'"]
|
|
|
|
* ["t.rb:3:in `/': \e[1mdivided by 0 (\e[1;4mZeroDivisionError\e[m\e[1m)\e[m",
|
|
|
|
* "\tfrom t.rb:3:in `baz'",
|
|
|
|
* "\tfrom t.rb:10:in `bar'",
|
|
|
|
* "\tfrom t.rb:11:in `foo'",
|
|
|
|
* "\tfrom t.rb:12:in `<main>'"]
|
2018-03-22 11:26:23 +03:00
|
|
|
*
|
2024-10-08 20:36:17 +03:00
|
|
|
* An overriding method should be careful with ANSI code enhancements;
|
2024-06-26 20:31:40 +03:00
|
|
|
* see {Messages}[rdoc-ref:exceptions.md@Messages].
|
2017-12-12 14:47:16 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
2018-03-22 11:26:23 +03:00
|
|
|
exc_full_message(int argc, VALUE *argv, VALUE exc)
|
|
|
|
{
|
2018-04-11 11:03:43 +03:00
|
|
|
VALUE opt, str, emesg, errat;
|
2022-02-01 09:58:39 +03:00
|
|
|
VALUE highlight, order;
|
2018-03-22 11:26:23 +03:00
|
|
|
|
|
|
|
rb_scan_args(argc, argv, "0:", &opt);
|
2022-02-01 09:58:39 +03:00
|
|
|
|
2022-02-02 09:08:10 +03:00
|
|
|
highlight = check_highlight_keyword(opt, 1);
|
2022-02-01 09:58:39 +03:00
|
|
|
order = check_order_keyword(opt);
|
|
|
|
|
2022-02-02 09:36:13 +03:00
|
|
|
{
|
|
|
|
if (NIL_P(opt)) opt = rb_hash_new();
|
2022-02-07 10:05:45 +03:00
|
|
|
rb_hash_aset(opt, sym_highlight, highlight);
|
2022-02-02 09:36:13 +03:00
|
|
|
}
|
|
|
|
|
2018-03-22 11:26:23 +03:00
|
|
|
str = rb_str_new2("");
|
|
|
|
errat = rb_get_backtrace(exc);
|
2022-02-01 11:59:31 +03:00
|
|
|
emesg = rb_get_detailed_message(exc, opt);
|
2018-03-22 11:26:23 +03:00
|
|
|
|
2022-02-01 11:59:31 +03:00
|
|
|
rb_error_write(exc, emesg, errat, str, opt, highlight, order);
|
2017-12-12 14:47:16 +03:00
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2003-12-21 10:28:54 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2024-06-26 20:31:40 +03:00
|
|
|
* message -> string
|
|
|
|
*
|
|
|
|
* Returns #to_s.
|
2003-12-21 10:28:54 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* See {Messages}[rdoc-ref:exceptions.md@Messages].
|
2003-12-21 10:28:54 +03:00
|
|
|
*/
|
|
|
|
|
* gc.c (Init_stack): stack region is far smaller than usual if
pthread is used.
* marshal.c (w_extended): singleton methods should not be checked
when dumping via marshal_dump() or _dump(). [ruby-talk:85909]
* file.c (getcwdofdrv): avoid using getcwd() directly, use
my_getcwd() instead.
* merged NeXT, OpenStep, Rhapsody ports patch from Eric Sunshine
<sunshine@sunshineco.com>. [ruby-core:01596]
* marshal.c (w_object): LINK check earlier than anything else,
i.e. do not dump TYPE_IVAR for already dumped objects.
(ruby-bugs PR#1220)
* eval.c (rb_eval): call "inherited" only when a new class is
generated; not on reopening.
* eval.c (eval): prepend error position in evaluating string to
* configure.in: revived NextStep, OpenStep, and Rhapsody ports which
had become unbuildable; enhanced --enable-fat-binary option so that
it accepts a list of desired architectures (rather than assuming a
fixed list), or defaults to a platform-appropriate list if user does
not provide an explicit list; made the default list of architectures
for MAB (fat binary) more comprehensive; now uses -fno-common even
when building the interpreter (in addition to using it for
extensions), thus allowing the interpreter to be embedded into a
plugin module of an external project (in addition to allowing
embedding directly into an application); added checks for
<netinet/in_systm.h> (needed by `socket' extension) and getcwd(); now
ensures that -I/usr/local/include is employed when extensions'
extconf.rb scripts invoke have_header() since extension checks on
NextStep and OpenStep will fail without it if the desired resource
resides in the /usr/local tree; fixed formatting of --help message.
* Makefile.in: $(LIBRUBY_A) rule now deletes the archive before
invoking $(AR) since `ar' on Apple/NeXT can not "update" MAB archives
(see configure's --enable-fat-binary option); added rule for new
missing/getcwd.c.
* defines.h: fixed endian handling during MAB build (see configure's
--enable-fat-binary option) to ensure that all portions of the
project see the correct WORDS_BIGENDIAN value (some extension modules
were getting the wrong endian setting); added missing constants
GETPGRP_VOID, WNOHANG, WUNTRACED, X_OK, and type pid_t for NextStep
and OpenStep; removed unnecessary and problematic HAVE_SYS_WAIT_H
define in NeXT section.
* dir.c: do not allow NAMLEN() macro to trust dirent::d_namlen on
NextStep since, on some installations, this value always resolves
uselessly to zero.
* dln.c: added error reporting to NextStep extension loader since the
previous behavior of failing silently was not useful; now ensures
that NSLINKMODULE_OPTION_BINDNOW compatibility constant is defined
for OpenStep and Rhapsody; no longer includes <mach-o/dyld.h> twice
on Rhapsody since this header lacks multiple-include protection,
which resulted in "redefinition" compilation errors.
* main.c: also create hard reference to objc_msgSend() on NeXT
platforms (in addition to Apple platforms).
* lib/mkmf.rb: now exports XCFLAGS from configure script to extension
makefiles so that extensions can be built MAB (see configure's
--enable-fat-binary option); also utilize XCFLAGS in cc_command()
(but not cpp_command() because MAB flags are incompatible with
direct invocation of `cpp').
* ext/curses/extconf.rb: now additionally checks for presence of these
curses functions which are not present on NextStep or Openstep:
bkgd(), bkgdset(), color(), curs(), getbkgd(), init(), scrl(), set(),
setscrreg(), wattroff(), wattron(), wattrset(), wbkgd(), wbkgdset(),
wscrl(), wsetscrreg()
* ext/curses/curses.c: added appropriate #ifdef's for additional set of
curses functions now checked by extconf.rb; fixed curses_bkgd() and
window_bkgd() to correctly return boolean result rather than numeric
result; fixed window_getbkgd() to correctly signal an error by
returning nil rather than -1.
* ext/etc/etc.c: setup_passwd() and setup_group() now check for null
pointers before invoking rb_tainted_str_new2() upon fields extracted
from `struct passwd' and `struct group' since null pointers in some
fields are common on NextStep/OpenStep (especially so for the
`pw_comment' field) and rb_tainted_str_new2() throws an exception
when it receives a null pointer.
* ext/pty/pty.c: include "util.h" for strdup()/ruby_strdup() for
platforms such as NextStep and OpenStep which lack strdup().
* ext/socket/getaddrinfo.c: cast first argument of getservbyname(),
gethostbyaddr(), and gethostbyname() from (const char*) to non-const
(char*) for older platforms such as NextStep and OpenStep.
* ext/socket/socket.c: include "util.h" for strdup()/ruby_strdup() for
platforms such as NextStep and OpenStep which lack strdup(); include
<netinet/in_systm.h> if present for NextStep and OpenStep; cast first
argument of gethostbyaddr() and getservbyname() from (const char*) to
non-const (char*) for older platforms.
* ext/syslog/syslog.c: include "util.h" for strdup()/ruby_strdup() for
platforms such as NextStep and OpenStep which lack strdup().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5002 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2003-11-22 07:00:03 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
exc_message(VALUE exc)
|
* gc.c (Init_stack): stack region is far smaller than usual if
pthread is used.
* marshal.c (w_extended): singleton methods should not be checked
when dumping via marshal_dump() or _dump(). [ruby-talk:85909]
* file.c (getcwdofdrv): avoid using getcwd() directly, use
my_getcwd() instead.
* merged NeXT, OpenStep, Rhapsody ports patch from Eric Sunshine
<sunshine@sunshineco.com>. [ruby-core:01596]
* marshal.c (w_object): LINK check earlier than anything else,
i.e. do not dump TYPE_IVAR for already dumped objects.
(ruby-bugs PR#1220)
* eval.c (rb_eval): call "inherited" only when a new class is
generated; not on reopening.
* eval.c (eval): prepend error position in evaluating string to
* configure.in: revived NextStep, OpenStep, and Rhapsody ports which
had become unbuildable; enhanced --enable-fat-binary option so that
it accepts a list of desired architectures (rather than assuming a
fixed list), or defaults to a platform-appropriate list if user does
not provide an explicit list; made the default list of architectures
for MAB (fat binary) more comprehensive; now uses -fno-common even
when building the interpreter (in addition to using it for
extensions), thus allowing the interpreter to be embedded into a
plugin module of an external project (in addition to allowing
embedding directly into an application); added checks for
<netinet/in_systm.h> (needed by `socket' extension) and getcwd(); now
ensures that -I/usr/local/include is employed when extensions'
extconf.rb scripts invoke have_header() since extension checks on
NextStep and OpenStep will fail without it if the desired resource
resides in the /usr/local tree; fixed formatting of --help message.
* Makefile.in: $(LIBRUBY_A) rule now deletes the archive before
invoking $(AR) since `ar' on Apple/NeXT can not "update" MAB archives
(see configure's --enable-fat-binary option); added rule for new
missing/getcwd.c.
* defines.h: fixed endian handling during MAB build (see configure's
--enable-fat-binary option) to ensure that all portions of the
project see the correct WORDS_BIGENDIAN value (some extension modules
were getting the wrong endian setting); added missing constants
GETPGRP_VOID, WNOHANG, WUNTRACED, X_OK, and type pid_t for NextStep
and OpenStep; removed unnecessary and problematic HAVE_SYS_WAIT_H
define in NeXT section.
* dir.c: do not allow NAMLEN() macro to trust dirent::d_namlen on
NextStep since, on some installations, this value always resolves
uselessly to zero.
* dln.c: added error reporting to NextStep extension loader since the
previous behavior of failing silently was not useful; now ensures
that NSLINKMODULE_OPTION_BINDNOW compatibility constant is defined
for OpenStep and Rhapsody; no longer includes <mach-o/dyld.h> twice
on Rhapsody since this header lacks multiple-include protection,
which resulted in "redefinition" compilation errors.
* main.c: also create hard reference to objc_msgSend() on NeXT
platforms (in addition to Apple platforms).
* lib/mkmf.rb: now exports XCFLAGS from configure script to extension
makefiles so that extensions can be built MAB (see configure's
--enable-fat-binary option); also utilize XCFLAGS in cc_command()
(but not cpp_command() because MAB flags are incompatible with
direct invocation of `cpp').
* ext/curses/extconf.rb: now additionally checks for presence of these
curses functions which are not present on NextStep or Openstep:
bkgd(), bkgdset(), color(), curs(), getbkgd(), init(), scrl(), set(),
setscrreg(), wattroff(), wattron(), wattrset(), wbkgd(), wbkgdset(),
wscrl(), wsetscrreg()
* ext/curses/curses.c: added appropriate #ifdef's for additional set of
curses functions now checked by extconf.rb; fixed curses_bkgd() and
window_bkgd() to correctly return boolean result rather than numeric
result; fixed window_getbkgd() to correctly signal an error by
returning nil rather than -1.
* ext/etc/etc.c: setup_passwd() and setup_group() now check for null
pointers before invoking rb_tainted_str_new2() upon fields extracted
from `struct passwd' and `struct group' since null pointers in some
fields are common on NextStep/OpenStep (especially so for the
`pw_comment' field) and rb_tainted_str_new2() throws an exception
when it receives a null pointer.
* ext/pty/pty.c: include "util.h" for strdup()/ruby_strdup() for
platforms such as NextStep and OpenStep which lack strdup().
* ext/socket/getaddrinfo.c: cast first argument of getservbyname(),
gethostbyaddr(), and gethostbyname() from (const char*) to non-const
(char*) for older platforms such as NextStep and OpenStep.
* ext/socket/socket.c: include "util.h" for strdup()/ruby_strdup() for
platforms such as NextStep and OpenStep which lack strdup(); include
<netinet/in_systm.h> if present for NextStep and OpenStep; cast first
argument of gethostbyaddr() and getservbyname() from (const char*) to
non-const (char*) for older platforms.
* ext/syslog/syslog.c: include "util.h" for strdup()/ruby_strdup() for
platforms such as NextStep and OpenStep which lack strdup().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5002 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2003-11-22 07:00:03 +03:00
|
|
|
{
|
2015-02-16 07:08:52 +03:00
|
|
|
return rb_funcallv(exc, idTo_s, 0, 0);
|
* gc.c (Init_stack): stack region is far smaller than usual if
pthread is used.
* marshal.c (w_extended): singleton methods should not be checked
when dumping via marshal_dump() or _dump(). [ruby-talk:85909]
* file.c (getcwdofdrv): avoid using getcwd() directly, use
my_getcwd() instead.
* merged NeXT, OpenStep, Rhapsody ports patch from Eric Sunshine
<sunshine@sunshineco.com>. [ruby-core:01596]
* marshal.c (w_object): LINK check earlier than anything else,
i.e. do not dump TYPE_IVAR for already dumped objects.
(ruby-bugs PR#1220)
* eval.c (rb_eval): call "inherited" only when a new class is
generated; not on reopening.
* eval.c (eval): prepend error position in evaluating string to
* configure.in: revived NextStep, OpenStep, and Rhapsody ports which
had become unbuildable; enhanced --enable-fat-binary option so that
it accepts a list of desired architectures (rather than assuming a
fixed list), or defaults to a platform-appropriate list if user does
not provide an explicit list; made the default list of architectures
for MAB (fat binary) more comprehensive; now uses -fno-common even
when building the interpreter (in addition to using it for
extensions), thus allowing the interpreter to be embedded into a
plugin module of an external project (in addition to allowing
embedding directly into an application); added checks for
<netinet/in_systm.h> (needed by `socket' extension) and getcwd(); now
ensures that -I/usr/local/include is employed when extensions'
extconf.rb scripts invoke have_header() since extension checks on
NextStep and OpenStep will fail without it if the desired resource
resides in the /usr/local tree; fixed formatting of --help message.
* Makefile.in: $(LIBRUBY_A) rule now deletes the archive before
invoking $(AR) since `ar' on Apple/NeXT can not "update" MAB archives
(see configure's --enable-fat-binary option); added rule for new
missing/getcwd.c.
* defines.h: fixed endian handling during MAB build (see configure's
--enable-fat-binary option) to ensure that all portions of the
project see the correct WORDS_BIGENDIAN value (some extension modules
were getting the wrong endian setting); added missing constants
GETPGRP_VOID, WNOHANG, WUNTRACED, X_OK, and type pid_t for NextStep
and OpenStep; removed unnecessary and problematic HAVE_SYS_WAIT_H
define in NeXT section.
* dir.c: do not allow NAMLEN() macro to trust dirent::d_namlen on
NextStep since, on some installations, this value always resolves
uselessly to zero.
* dln.c: added error reporting to NextStep extension loader since the
previous behavior of failing silently was not useful; now ensures
that NSLINKMODULE_OPTION_BINDNOW compatibility constant is defined
for OpenStep and Rhapsody; no longer includes <mach-o/dyld.h> twice
on Rhapsody since this header lacks multiple-include protection,
which resulted in "redefinition" compilation errors.
* main.c: also create hard reference to objc_msgSend() on NeXT
platforms (in addition to Apple platforms).
* lib/mkmf.rb: now exports XCFLAGS from configure script to extension
makefiles so that extensions can be built MAB (see configure's
--enable-fat-binary option); also utilize XCFLAGS in cc_command()
(but not cpp_command() because MAB flags are incompatible with
direct invocation of `cpp').
* ext/curses/extconf.rb: now additionally checks for presence of these
curses functions which are not present on NextStep or Openstep:
bkgd(), bkgdset(), color(), curs(), getbkgd(), init(), scrl(), set(),
setscrreg(), wattroff(), wattron(), wattrset(), wbkgd(), wbkgdset(),
wscrl(), wsetscrreg()
* ext/curses/curses.c: added appropriate #ifdef's for additional set of
curses functions now checked by extconf.rb; fixed curses_bkgd() and
window_bkgd() to correctly return boolean result rather than numeric
result; fixed window_getbkgd() to correctly signal an error by
returning nil rather than -1.
* ext/etc/etc.c: setup_passwd() and setup_group() now check for null
pointers before invoking rb_tainted_str_new2() upon fields extracted
from `struct passwd' and `struct group' since null pointers in some
fields are common on NextStep/OpenStep (especially so for the
`pw_comment' field) and rb_tainted_str_new2() throws an exception
when it receives a null pointer.
* ext/pty/pty.c: include "util.h" for strdup()/ruby_strdup() for
platforms such as NextStep and OpenStep which lack strdup().
* ext/socket/getaddrinfo.c: cast first argument of getservbyname(),
gethostbyaddr(), and gethostbyname() from (const char*) to non-const
(char*) for older platforms such as NextStep and OpenStep.
* ext/socket/socket.c: include "util.h" for strdup()/ruby_strdup() for
platforms such as NextStep and OpenStep which lack strdup(); include
<netinet/in_systm.h> if present for NextStep and OpenStep; cast first
argument of gethostbyaddr() and getservbyname() from (const char*) to
non-const (char*) for older platforms.
* ext/syslog/syslog.c: include "util.h" for strdup()/ruby_strdup() for
platforms such as NextStep and OpenStep which lack strdup().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5002 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2003-11-22 07:00:03 +03:00
|
|
|
}
|
|
|
|
|
2022-02-01 11:59:31 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2024-06-26 20:31:40 +03:00
|
|
|
* detailed_message(highlight: false, **kwargs) -> string
|
|
|
|
*
|
|
|
|
* Returns the message string with enhancements:
|
|
|
|
*
|
|
|
|
* - Includes the exception class name in the first line.
|
|
|
|
* - If the value of keyword +highlight+ is +true+,
|
|
|
|
* includes bolding and underlining ANSI codes (see below)
|
|
|
|
* to enhance the appearance of the message.
|
2022-02-01 11:59:31 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* Examples:
|
2022-02-01 11:59:31 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* begin
|
|
|
|
* 1 / 0
|
|
|
|
* rescue => x
|
|
|
|
* p x.message
|
|
|
|
* p x.detailed_message # Class name added.
|
|
|
|
* p x.detailed_message(highlight: true) # Class name, bolding, and underlining added.
|
|
|
|
* end
|
2022-02-01 11:59:31 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* Output:
|
2022-02-01 11:59:31 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* "divided by 0"
|
|
|
|
* "divided by 0 (ZeroDivisionError)"
|
|
|
|
* "\e[1mdivided by 0 (\e[1;4mZeroDivisionError\e[m\e[1m)\e[m"
|
2022-07-12 07:50:04 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* This method is overridden by some gems in the Ruby standard library to add information:
|
2022-07-12 07:50:04 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* - DidYouMean::Correctable#detailed_message.
|
|
|
|
* - ErrorHighlight::CoreExt#detailed_message.
|
|
|
|
* - SyntaxSuggest#detailed_message.
|
2022-07-12 07:50:04 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* An overriding method must be tolerant of passed keyword arguments,
|
|
|
|
* which may include (but may not be limited to):
|
|
|
|
*
|
|
|
|
* - +:highlight+.
|
|
|
|
* - +:did_you_mean+.
|
|
|
|
* - +:error_highlight+.
|
|
|
|
* - +:syntax_suggest+.
|
|
|
|
*
|
2024-10-08 20:36:17 +03:00
|
|
|
* An overriding method should also be careful with ANSI code enhancements;
|
2024-06-26 20:31:40 +03:00
|
|
|
* see {Messages}[rdoc-ref:exceptions.md@Messages].
|
2022-02-01 11:59:31 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
exc_detailed_message(int argc, VALUE *argv, VALUE exc)
|
|
|
|
{
|
|
|
|
VALUE opt;
|
|
|
|
|
|
|
|
rb_scan_args(argc, argv, "0:", &opt);
|
|
|
|
|
2022-02-02 09:08:10 +03:00
|
|
|
VALUE highlight = check_highlight_keyword(opt, 0);
|
2022-02-01 11:59:31 +03:00
|
|
|
|
2024-01-02 18:07:14 +03:00
|
|
|
extern VALUE rb_decorate_message(const VALUE eclass, VALUE emesg, int highlight);
|
2022-02-01 11:59:31 +03:00
|
|
|
|
2022-02-02 09:08:10 +03:00
|
|
|
return rb_decorate_message(CLASS_OF(exc), rb_get_message(exc), RTEST(highlight));
|
2022-02-01 11:59:31 +03:00
|
|
|
}
|
|
|
|
|
2003-12-21 10:28:54 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2024-06-26 20:31:40 +03:00
|
|
|
* inspect -> string
|
|
|
|
*
|
|
|
|
* Returns a string representation of +self+:
|
|
|
|
*
|
|
|
|
* x = RuntimeError.new('Boom')
|
|
|
|
* x.inspect # => "#<RuntimeError: Boom>"
|
|
|
|
* x = RuntimeError.new
|
|
|
|
* x.inspect # => "#<RuntimeError: RuntimeError>"
|
2003-12-21 10:28:54 +03:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
exc_inspect(VALUE exc)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
1998-01-16 15:19:22 +03:00
|
|
|
VALUE str, klass;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
1998-01-16 15:19:22 +03:00
|
|
|
klass = CLASS_OF(exc);
|
1999-01-20 07:59:39 +03:00
|
|
|
exc = rb_obj_as_string(exc);
|
2006-08-31 14:47:44 +04:00
|
|
|
if (RSTRING_LEN(exc) == 0) {
|
2019-06-13 12:07:19 +03:00
|
|
|
return rb_class_name(klass);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
1998-01-16 15:19:22 +03:00
|
|
|
|
2001-05-30 13:12:34 +04:00
|
|
|
str = rb_str_buf_new2("#<");
|
2004-01-19 12:19:31 +03:00
|
|
|
klass = rb_class_name(klass);
|
2001-05-30 13:12:34 +04:00
|
|
|
rb_str_buf_append(str, klass);
|
2022-09-23 10:40:59 +03:00
|
|
|
|
|
|
|
if (RTEST(rb_str_include(exc, rb_str_new2("\n")))) {
|
|
|
|
rb_str_catf(str, ":%+"PRIsVALUE, exc);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rb_str_buf_cat(str, ": ", 2);
|
|
|
|
rb_str_buf_append(str, exc);
|
|
|
|
}
|
|
|
|
|
2001-05-30 13:12:34 +04:00
|
|
|
rb_str_buf_cat(str, ">", 1);
|
1998-01-16 15:19:22 +03:00
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2003-12-21 10:28:54 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2024-06-26 20:31:40 +03:00
|
|
|
* backtrace -> array or nil
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* Returns a backtrace value for +self+;
|
|
|
|
* the returned value depends on the form of the stored backtrace value:
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* - \Array of Thread::Backtrace::Location objects:
|
|
|
|
* returns the array of strings given by
|
|
|
|
* <tt>Exception#backtrace_locations.map {|loc| loc.to_s }</tt>.
|
|
|
|
* This is the normal case, where the backtrace value was stored by Kernel#raise.
|
|
|
|
* - \Array of strings: returns that array.
|
|
|
|
* This is the unusual case, where the backtrace value was explicitly
|
|
|
|
* stored as an array of strings.
|
|
|
|
* - +nil+: returns +nil+.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* Example:
|
2019-08-14 17:35:47 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* begin
|
|
|
|
* 1 / 0
|
|
|
|
* rescue => x
|
|
|
|
* x.backtrace.take(2)
|
|
|
|
* end
|
|
|
|
* # => ["(irb):132:in `/'", "(irb):132:in `<top (required)>'"]
|
2019-08-14 17:35:47 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* see {Backtraces}[rdoc-ref:exceptions.md@Backtraces].
|
|
|
|
*/
|
2003-12-21 10:28:54 +03:00
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
exc_backtrace(VALUE exc)
|
1999-01-20 07:59:39 +03:00
|
|
|
{
|
2012-05-24 10:09:23 +04:00
|
|
|
VALUE obj;
|
1999-08-13 09:45:20 +04:00
|
|
|
|
2015-02-16 06:58:28 +03:00
|
|
|
obj = rb_attr_get(exc, id_bt);
|
2012-05-24 10:09:23 +04:00
|
|
|
|
|
|
|
if (rb_backtrace_p(obj)) {
|
|
|
|
obj = rb_backtrace_to_str_ary(obj);
|
2015-02-23 01:57:18 +03:00
|
|
|
/* rb_ivar_set(exc, id_bt, obj); */
|
2012-05-24 10:09:23 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return obj;
|
1999-01-20 07:59:39 +03:00
|
|
|
}
|
|
|
|
|
2019-11-18 06:13:08 +03:00
|
|
|
static VALUE rb_check_backtrace(VALUE);
|
|
|
|
|
2016-11-13 08:25:53 +03:00
|
|
|
VALUE
|
|
|
|
rb_get_backtrace(VALUE exc)
|
|
|
|
{
|
|
|
|
ID mid = id_backtrace;
|
2018-05-14 11:33:14 +03:00
|
|
|
VALUE info;
|
2016-11-13 08:25:54 +03:00
|
|
|
if (rb_method_basic_definition_p(CLASS_OF(exc), id_backtrace)) {
|
2018-05-14 11:33:14 +03:00
|
|
|
VALUE klass = rb_eException;
|
2017-10-29 16:19:14 +03:00
|
|
|
rb_execution_context_t *ec = GET_EC();
|
2016-11-13 08:25:54 +03:00
|
|
|
if (NIL_P(exc))
|
|
|
|
return Qnil;
|
2017-10-29 16:19:14 +03:00
|
|
|
EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_CALL, exc, mid, mid, klass, Qundef);
|
2016-11-13 08:25:54 +03:00
|
|
|
info = exc_backtrace(exc);
|
2017-10-29 16:19:14 +03:00
|
|
|
EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_RETURN, exc, mid, mid, klass, info);
|
2016-11-13 08:25:54 +03:00
|
|
|
}
|
2018-05-14 11:33:14 +03:00
|
|
|
else {
|
|
|
|
info = rb_funcallv(exc, mid, 0, 0);
|
|
|
|
}
|
|
|
|
if (NIL_P(info)) return Qnil;
|
|
|
|
return rb_check_backtrace(info);
|
2016-11-13 08:25:53 +03:00
|
|
|
}
|
|
|
|
|
2013-12-13 08:31:06 +04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2024-06-26 20:31:40 +03:00
|
|
|
* backtrace_locations -> array or nil
|
|
|
|
*
|
|
|
|
* Returns a backtrace value for +self+;
|
|
|
|
* the returned value depends on the form of the stored backtrace value:
|
2013-12-13 08:31:06 +04:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* - \Array of Thread::Backtrace::Location objects: returns that array.
|
|
|
|
* - \Array of strings or +nil+: returns +nil+.
|
|
|
|
*
|
|
|
|
* Example:
|
2013-12-13 08:31:06 +04:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* begin
|
|
|
|
* 1 / 0
|
|
|
|
* rescue => x
|
|
|
|
* x.backtrace_locations.take(2)
|
|
|
|
* end
|
|
|
|
* # => ["(irb):150:in `/'", "(irb):150:in `<top (required)>'"]
|
|
|
|
*
|
|
|
|
* See {Backtraces}[rdoc-ref:exceptions.md@Backtraces].
|
2013-12-13 08:31:06 +04:00
|
|
|
*/
|
|
|
|
static VALUE
|
|
|
|
exc_backtrace_locations(VALUE exc)
|
|
|
|
{
|
|
|
|
VALUE obj;
|
|
|
|
|
2015-02-16 06:58:28 +03:00
|
|
|
obj = rb_attr_get(exc, id_bt_locations);
|
2013-12-13 08:31:06 +04:00
|
|
|
if (!NIL_P(obj)) {
|
|
|
|
obj = rb_backtrace_to_location_ary(obj);
|
|
|
|
}
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2019-11-18 06:13:08 +03:00
|
|
|
static VALUE
|
2007-07-19 14:24:17 +04:00
|
|
|
rb_check_backtrace(VALUE bt)
|
1999-01-20 07:59:39 +03:00
|
|
|
{
|
2002-08-21 19:47:54 +04:00
|
|
|
long i;
|
2024-02-19 13:30:26 +03:00
|
|
|
static const char err[] = "backtrace must be an Array of String or an Array of Thread::Backtrace::Location";
|
1999-01-20 07:59:39 +03:00
|
|
|
|
|
|
|
if (!NIL_P(bt)) {
|
2012-04-13 19:34:34 +04:00
|
|
|
if (RB_TYPE_P(bt, T_STRING)) return rb_ary_new3(1, bt);
|
2012-05-24 10:09:23 +04:00
|
|
|
if (rb_backtrace_p(bt)) return bt;
|
2012-04-13 19:34:34 +04:00
|
|
|
if (!RB_TYPE_P(bt, T_ARRAY)) {
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_raise(rb_eTypeError, err);
|
|
|
|
}
|
2006-09-02 18:42:08 +04:00
|
|
|
for (i=0;i<RARRAY_LEN(bt);i++) {
|
2013-06-20 08:14:09 +04:00
|
|
|
VALUE e = RARRAY_AREF(bt, i);
|
|
|
|
if (!RB_TYPE_P(e, T_STRING)) {
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_raise(rb_eTypeError, err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return bt;
|
|
|
|
}
|
|
|
|
|
2003-12-21 10:28:54 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2024-06-26 20:31:40 +03:00
|
|
|
* set_backtrace(value) -> value
|
|
|
|
*
|
|
|
|
* Sets the backtrace value for +self+; returns the given +value:
|
|
|
|
*
|
|
|
|
* x = RuntimeError.new('Boom')
|
|
|
|
* x.set_backtrace(%w[foo bar baz]) # => ["foo", "bar", "baz"]
|
|
|
|
* x.backtrace # => ["foo", "bar", "baz"]
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* The given +value+ must be an array of strings, a single string, or +nil+.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* Does not affect the value returned by #backtrace_locations.
|
|
|
|
*
|
|
|
|
* See {Backtraces}[rdoc-ref:exceptions.md@Backtraces].
|
2003-12-21 10:28:54 +03:00
|
|
|
*/
|
|
|
|
|
2012-05-24 10:36:44 +04:00
|
|
|
static VALUE
|
|
|
|
exc_set_backtrace(VALUE exc, VALUE bt)
|
|
|
|
{
|
2024-02-19 13:30:26 +03:00
|
|
|
VALUE btobj = rb_location_ary_to_backtrace(bt);
|
|
|
|
if (RTEST(btobj)) {
|
|
|
|
rb_ivar_set(exc, id_bt, btobj);
|
|
|
|
rb_ivar_set(exc, id_bt_locations, btobj);
|
|
|
|
return bt;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return rb_ivar_set(exc, id_bt, rb_check_backtrace(bt));
|
|
|
|
}
|
2012-05-24 10:36:44 +04:00
|
|
|
}
|
|
|
|
|
2023-03-07 08:34:31 +03:00
|
|
|
VALUE
|
2012-05-24 10:09:23 +04:00
|
|
|
rb_exc_set_backtrace(VALUE exc, VALUE bt)
|
1999-01-20 07:59:39 +03:00
|
|
|
{
|
2012-05-24 10:36:44 +04:00
|
|
|
return exc_set_backtrace(exc, bt);
|
1999-01-20 07:59:39 +03:00
|
|
|
}
|
|
|
|
|
2014-02-01 01:31:12 +04:00
|
|
|
/*
|
2024-06-26 20:31:40 +03:00
|
|
|
* call-seq:
|
|
|
|
* cause -> exception or nil
|
|
|
|
*
|
|
|
|
* Returns the previous value of global variable <tt>$!</tt>,
|
|
|
|
* which may be +nil+
|
|
|
|
* (see {Global Variables}[rdoc-ref:exceptions.md@Global+Variables]):
|
|
|
|
*
|
|
|
|
* begin
|
|
|
|
* raise('Boom 0')
|
|
|
|
* rescue => x0
|
|
|
|
* puts "Exception: #{x0}; $!: #{$!}; cause: #{x0.cause.inspect}."
|
|
|
|
* begin
|
|
|
|
* raise('Boom 1')
|
|
|
|
* rescue => x1
|
|
|
|
* puts "Exception: #{x1}; $!: #{$!}; cause: #{x1.cause}."
|
|
|
|
* begin
|
|
|
|
* raise('Boom 2')
|
|
|
|
* rescue => x2
|
|
|
|
* puts "Exception: #{x2}; $!: #{$!}; cause: #{x2.cause}."
|
|
|
|
* end
|
|
|
|
* end
|
|
|
|
* end
|
|
|
|
*
|
|
|
|
* Output:
|
|
|
|
*
|
|
|
|
* Exception: Boom 0; $!: Boom 0; cause: nil.
|
|
|
|
* Exception: Boom 1; $!: Boom 1; cause: Boom 0.
|
|
|
|
* Exception: Boom 2; $!: Boom 2; cause: Boom 1.
|
2014-02-01 01:31:12 +04:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2015-12-08 18:07:41 +03:00
|
|
|
static VALUE
|
2013-11-10 17:16:33 +04:00
|
|
|
exc_cause(VALUE exc)
|
|
|
|
{
|
|
|
|
return rb_attr_get(exc, id_cause);
|
|
|
|
}
|
|
|
|
|
2012-01-14 07:00:24 +04:00
|
|
|
static VALUE
|
|
|
|
try_convert_to_exception(VALUE obj)
|
|
|
|
{
|
2014-11-16 11:33:35 +03:00
|
|
|
return rb_check_funcall(obj, idException, 0, 0);
|
2012-01-14 07:00:24 +04:00
|
|
|
}
|
|
|
|
|
2004-08-28 18:14:11 +04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2024-06-26 20:31:40 +03:00
|
|
|
* self == object -> true or false
|
|
|
|
*
|
|
|
|
* Returns whether +object+ is the same class as +self+
|
|
|
|
* and its #message and #backtrace are equal to those of +self+.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2004-08-28 18:14:11 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
exc_equal(VALUE exc, VALUE obj)
|
2004-08-28 18:14:11 +04:00
|
|
|
{
|
2008-12-19 02:42:00 +03:00
|
|
|
VALUE mesg, backtrace;
|
2004-08-28 18:14:11 +04:00
|
|
|
|
|
|
|
if (exc == obj) return Qtrue;
|
2008-12-24 15:02:21 +03:00
|
|
|
|
2008-12-19 02:42:00 +03:00
|
|
|
if (rb_obj_class(exc) != rb_obj_class(obj)) {
|
2017-06-23 10:25:52 +03:00
|
|
|
int state;
|
2022-07-21 19:23:58 +03:00
|
|
|
|
2017-06-23 10:25:52 +03:00
|
|
|
obj = rb_protect(try_convert_to_exception, obj, &state);
|
2022-11-15 07:24:08 +03:00
|
|
|
if (state || UNDEF_P(obj)) {
|
2012-01-14 13:36:18 +04:00
|
|
|
rb_set_errinfo(Qnil);
|
|
|
|
return Qfalse;
|
|
|
|
}
|
2012-01-14 07:00:24 +04:00
|
|
|
if (rb_obj_class(exc) != rb_obj_class(obj)) return Qfalse;
|
2009-10-29 07:55:10 +03:00
|
|
|
mesg = rb_check_funcall(obj, id_message, 0, 0);
|
2022-11-15 07:24:08 +03:00
|
|
|
if (UNDEF_P(mesg)) return Qfalse;
|
2009-10-29 07:55:10 +03:00
|
|
|
backtrace = rb_check_funcall(obj, id_backtrace, 0, 0);
|
2022-11-15 07:24:08 +03:00
|
|
|
if (UNDEF_P(backtrace)) return Qfalse;
|
2008-12-19 02:42:00 +03:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
mesg = rb_attr_get(obj, id_mesg);
|
|
|
|
backtrace = exc_backtrace(obj);
|
|
|
|
}
|
2008-12-24 15:02:21 +03:00
|
|
|
|
2008-12-19 02:42:00 +03:00
|
|
|
if (!rb_equal(rb_attr_get(exc, id_mesg), mesg))
|
2004-08-28 18:14:11 +04:00
|
|
|
return Qfalse;
|
2021-09-15 02:11:05 +03:00
|
|
|
return rb_equal(exc_backtrace(exc), backtrace);
|
2004-08-28 18:14:11 +04:00
|
|
|
}
|
|
|
|
|
2003-12-29 06:56:22 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2011-12-08 17:50:10 +04:00
|
|
|
* SystemExit.new -> system_exit
|
|
|
|
* SystemExit.new(status) -> system_exit
|
|
|
|
* SystemExit.new(status, msg) -> system_exit
|
|
|
|
* SystemExit.new(msg) -> system_exit
|
2003-12-29 06:56:22 +03:00
|
|
|
*
|
2011-12-08 17:50:10 +04:00
|
|
|
* Create a new +SystemExit+ exception with the given status and message.
|
2011-12-11 05:48:21 +04:00
|
|
|
* Status is true, false, or an integer.
|
|
|
|
* If status is not given, true is used.
|
2003-12-29 06:56:22 +03:00
|
|
|
*/
|
|
|
|
|
2002-11-27 01:32:11 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
exit_initialize(int argc, VALUE *argv, VALUE exc)
|
2002-11-27 01:32:11 +03:00
|
|
|
{
|
2011-12-11 05:48:21 +04:00
|
|
|
VALUE status;
|
|
|
|
if (argc > 0) {
|
|
|
|
status = *argv;
|
2022-07-21 19:23:58 +03:00
|
|
|
|
2011-12-11 05:48:21 +04:00
|
|
|
switch (status) {
|
|
|
|
case Qtrue:
|
|
|
|
status = INT2FIX(EXIT_SUCCESS);
|
|
|
|
++argv;
|
|
|
|
--argc;
|
|
|
|
break;
|
|
|
|
case Qfalse:
|
|
|
|
status = INT2FIX(EXIT_FAILURE);
|
|
|
|
++argv;
|
|
|
|
--argc;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
status = rb_check_to_int(status);
|
|
|
|
if (NIL_P(status)) {
|
|
|
|
status = INT2FIX(EXIT_SUCCESS);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
#if EXIT_SUCCESS != 0
|
|
|
|
if (status == INT2FIX(0))
|
|
|
|
status = INT2FIX(EXIT_SUCCESS);
|
|
|
|
#endif
|
|
|
|
++argv;
|
|
|
|
--argc;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
status = INT2FIX(EXIT_SUCCESS);
|
2002-11-27 01:32:11 +03:00
|
|
|
}
|
2005-05-14 18:59:53 +04:00
|
|
|
rb_call_super(argc, argv);
|
2015-02-23 01:57:18 +03:00
|
|
|
rb_ivar_set(exc, id_status, status);
|
2002-11-27 01:32:11 +03:00
|
|
|
return exc;
|
|
|
|
}
|
|
|
|
|
2003-12-29 06:56:22 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2016-09-08 07:57:49 +03:00
|
|
|
* system_exit.status -> integer
|
2003-12-29 06:56:22 +03:00
|
|
|
*
|
|
|
|
* Return the status value associated with this system exit.
|
|
|
|
*/
|
|
|
|
|
2001-02-19 10:03:06 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
exit_status(VALUE exc)
|
2001-02-19 10:03:06 +03:00
|
|
|
{
|
2015-02-16 06:58:28 +03:00
|
|
|
return rb_attr_get(exc, id_status);
|
2001-02-19 10:03:06 +03:00
|
|
|
}
|
|
|
|
|
2004-07-16 06:17:59 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:31:22 +04:00
|
|
|
* system_exit.success? -> true or false
|
2004-07-16 06:17:59 +04:00
|
|
|
*
|
|
|
|
* Returns +true+ if exiting successful, +false+ if not.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
exit_success_p(VALUE exc)
|
2004-07-16 06:17:59 +04:00
|
|
|
{
|
2015-02-16 06:58:28 +03:00
|
|
|
VALUE status_val = rb_attr_get(exc, id_status);
|
2010-12-20 17:49:18 +03:00
|
|
|
int status;
|
|
|
|
|
|
|
|
if (NIL_P(status_val))
|
|
|
|
return Qtrue;
|
|
|
|
status = NUM2INT(status_val);
|
2021-09-15 02:11:05 +03:00
|
|
|
return RBOOL(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
|
2004-07-16 06:17:59 +04:00
|
|
|
}
|
|
|
|
|
2019-12-20 08:14:07 +03:00
|
|
|
static VALUE
|
|
|
|
err_init_recv(VALUE exc, VALUE recv)
|
|
|
|
{
|
2022-11-15 07:24:08 +03:00
|
|
|
if (!UNDEF_P(recv)) rb_ivar_set(exc, id_recv, recv);
|
2019-12-20 08:14:07 +03:00
|
|
|
return exc;
|
|
|
|
}
|
|
|
|
|
2019-04-06 10:02:11 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2019-12-20 08:14:07 +03:00
|
|
|
* FrozenError.new(msg=nil, receiver: nil) -> frozen_error
|
2019-04-06 10:02:11 +03:00
|
|
|
*
|
|
|
|
* Construct a new FrozenError exception. If given the <i>receiver</i>
|
|
|
|
* parameter may subsequently be examined using the FrozenError#receiver
|
|
|
|
* method.
|
|
|
|
*
|
|
|
|
* a = [].freeze
|
2019-12-21 23:21:20 +03:00
|
|
|
* raise FrozenError.new("can't modify frozen array", receiver: a)
|
2019-04-06 10:02:11 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
frozen_err_initialize(int argc, VALUE *argv, VALUE self)
|
|
|
|
{
|
2019-12-20 08:14:07 +03:00
|
|
|
ID keywords[1];
|
|
|
|
VALUE values[numberof(keywords)], options;
|
2019-04-06 10:02:11 +03:00
|
|
|
|
2019-12-20 08:14:07 +03:00
|
|
|
argc = rb_scan_args(argc, argv, "*:", NULL, &options);
|
|
|
|
keywords[0] = id_receiver;
|
|
|
|
rb_get_kwargs(options, keywords, 0, numberof(values), values);
|
2019-04-06 10:02:11 +03:00
|
|
|
rb_call_super(argc, argv);
|
2019-12-20 08:14:07 +03:00
|
|
|
err_init_recv(self, values[0]);
|
2019-04-06 10:02:11 +03:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2019-12-14 18:21:19 +03:00
|
|
|
/*
|
2019-12-21 23:21:20 +03:00
|
|
|
* Document-method: FrozenError#receiver
|
2019-12-14 18:21:19 +03:00
|
|
|
* call-seq:
|
|
|
|
* frozen_error.receiver -> object
|
|
|
|
*
|
|
|
|
* Return the receiver associated with this FrozenError exception.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define frozen_err_receiver name_err_receiver
|
|
|
|
|
2001-07-02 12:46:28 +04:00
|
|
|
void
|
|
|
|
rb_name_error(ID id, const char *fmt, ...)
|
|
|
|
{
|
2003-05-20 05:51:32 +04:00
|
|
|
VALUE exc, argv[2];
|
2001-07-02 12:46:28 +04:00
|
|
|
va_list args;
|
|
|
|
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
va_start(args, fmt);
|
* compile.c (insn_data_to_s_detail), file.c (rb_stat_inspect),
iseq.c (ruby_iseq_disasm_insn, ruby_iseq_disasm),
process.c (pst_message), re.c (match_inspect): use rb_str_catf.
* dir.c (dir_inspect), iseq.c (iseq_inspect, insn_operand_intern): use
rb_sprintf.
* error.c (rb_name_error, rb_raise, rb_loaderror, rb_fatal): use
rb_vsprintf.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18158 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-07-22 12:53:34 +04:00
|
|
|
argv[0] = rb_vsprintf(fmt, args);
|
2001-07-02 12:46:28 +04:00
|
|
|
va_end(args);
|
2003-05-20 05:51:32 +04:00
|
|
|
|
|
|
|
argv[1] = ID2SYM(id);
|
|
|
|
exc = rb_class_new_instance(2, argv, rb_eNameError);
|
2001-07-02 12:46:28 +04:00
|
|
|
rb_exc_raise(exc);
|
|
|
|
}
|
|
|
|
|
2011-07-23 19:05:03 +04:00
|
|
|
void
|
|
|
|
rb_name_error_str(VALUE str, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
VALUE exc, argv[2];
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
va_start(args, fmt);
|
|
|
|
argv[0] = rb_vsprintf(fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
argv[1] = str;
|
|
|
|
exc = rb_class_new_instance(2, argv, rb_eNameError);
|
|
|
|
rb_exc_raise(exc);
|
|
|
|
}
|
|
|
|
|
2018-04-12 06:48:48 +03:00
|
|
|
static VALUE
|
|
|
|
name_err_init_attr(VALUE exc, VALUE recv, VALUE method)
|
|
|
|
{
|
|
|
|
const rb_execution_context_t *ec = GET_EC();
|
|
|
|
rb_control_frame_t *cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp);
|
|
|
|
cfp = rb_vm_get_ruby_level_next_cfp(ec, cfp);
|
|
|
|
rb_ivar_set(exc, id_name, method);
|
2019-12-20 08:14:07 +03:00
|
|
|
err_init_recv(exc, recv);
|
Fix crash in NoMethodError for dummy frames
[Bug #19793]
Dummy frames are created at the top level when requiring another file.
While requiring a file, it will try to convert using encodings. Some of
these encodings will not respond to to_str. If method_missing is
redefined on Object, then it will call method_missing and attempt raise
an error. However, the iseq is invalid as it's a dummy frame so it will
write an invalid iseq to the created NoMethodError.
The following script crashes:
```
GC.stress = true
class Object
public :method_missing
end
File.write("/tmp/empty.rb", "")
require "/tmp/empty.rb"
```
With the following backtrace:
```
frame #0: 0x00000001000fa8b8 miniruby`RVALUE_MARKED(obj=4308637824) at gc.c:1638:12
frame #1: 0x00000001000fb440 miniruby`RVALUE_BLACK_P(obj=4308637824) at gc.c:1763:12
frame #2: 0x00000001000facdc miniruby`gc_writebarrier_incremental(a=4308637824, b=4308332208, objspace=0x000000010180b000) at gc.c:8822:9
frame #3: 0x00000001000faad8 miniruby`rb_gc_writebarrier(a=4308637824, b=4308332208) at gc.c:8864:17
frame #4: 0x000000010016aff0 miniruby`rb_obj_written(a=4308637824, oldv=36, b=4308332208, filename="../iseq.c", line=1279) at gc.h:804:9
frame #5: 0x0000000100162a60 miniruby`rb_obj_write(a=4308637824, slot=0x0000000100d09888, b=4308332208, filename="../iseq.c", line=1279) at gc.h:837:5
frame #6: 0x0000000100165b0c miniruby`iseqw_new(iseq=0x0000000100d09880) at iseq.c:1279:9
frame #7: 0x0000000100165a64 miniruby`rb_iseqw_new(iseq=0x0000000100d09880) at iseq.c:1289:12
frame #8: 0x00000001000d8324 miniruby`name_err_init_attr(exc=4309777920, recv=4304780496, method=827660) at error.c:1830:35
frame #9: 0x00000001000d1b80 miniruby`name_err_init(exc=4309777920, mesg=4308332496, recv=4304780496, method=827660) at error.c:1869:12
frame #10: 0x00000001000d1bd4 miniruby`rb_nomethod_err_new(mesg=4308332496, recv=4304780496, method=827660, args=4308332448, priv=0) at error.c:1957:5
frame #11: 0x000000010039049c miniruby`rb_make_no_method_exception(exc=4304914512, format=4308332496, obj=4304780496, argc=1, argv=0x000000016fdfab00, priv=0) at vm_eval.c:959:16
frame #12: 0x00000001003b3274 miniruby`raise_method_missing(ec=0x0000000100b06f40, argc=1, argv=0x000000016fdfab00, obj=4304780496, last_call_status=MISSING_NOENTRY) at vm_eval.c:999:15
frame #13: 0x00000001003945d4 miniruby`rb_method_missing(argc=1, argv=0x000000016fdfab00, obj=4304780496) at vm_eval.c:944:5
...
frame #23: 0x000000010038f5e4 miniruby`rb_vm_call_kw(ec=0x0000000100b06f40, recv=4304780496, id=2865, argc=1, argv=0x000000016fdfab00, me=0x0000000100cbfcf0, kw_splat=0) at vm_eval.c:326:12
frame #24: 0x00000001003c18e4 miniruby`call_method_entry(ec=0x0000000100b06f40, defined_class=4304927952, obj=4304780496, id=2865, cme=0x0000000100cbfcf0, argc=1, argv=0x000000016fdfab00, kw_splat=0) at vm_method.c:2720:20
frame #25: 0x00000001003c440c miniruby`check_funcall_exec(v=6171896792) at vm_eval.c:589:12
frame #26: 0x00000001000dec00 miniruby`rb_vrescue2(b_proc=(miniruby`check_funcall_exec at vm_eval.c:587), data1=6171896792, r_proc=(miniruby`check_funcall_failed at vm_eval.c:596), data2=6171896792, args="Pȗ") at eval.c:919:18
frame #27: 0x00000001000deab0 miniruby`rb_rescue2(b_proc=(miniruby`check_funcall_exec at vm_eval.c:587), data1=6171896792, r_proc=(miniruby`check_funcall_failed at vm_eval.c:596), data2=6171896792) at eval.c:900:17
frame #28: 0x000000010039008c miniruby`check_funcall_missing(ec=0x0000000100b06f40, klass=4304923536, recv=4304780496, mid=3233, argc=0, argv=0x0000000000000000, respond=-1, def=36, kw_splat=0) at vm_eval.c:666:15
frame #29: 0x000000010038fa60 miniruby`rb_check_funcall_default_kw(recv=4304780496, mid=3233, argc=0, argv=0x0000000000000000, def=36, kw_splat=0) at vm_eval.c:703:21
frame #30: 0x000000010038fb04 miniruby`rb_check_funcall(recv=4304780496, mid=3233, argc=0, argv=0x0000000000000000) at vm_eval.c:685:12
frame #31: 0x00000001001c469c miniruby`convert_type_with_id(val=4304780496, tname="String", method=3233, raise=0, index=-1) at object.c:3061:15
frame #32: 0x00000001001c4a4c miniruby`rb_check_convert_type_with_id(val=4304780496, type=5, tname="String", method=3233) at object.c:3153:9
frame #33: 0x00000001002d59f8 miniruby`rb_check_string_type(str=4304780496) at string.c:2571:11
frame #34: 0x000000010014b7b0 miniruby`io_encoding_set(fptr=0x0000000100d09ca0, v1=4304780496, v2=4, opt=4) at io.c:11655:19
frame #35: 0x0000000100139a58 miniruby`rb_io_set_encoding(argc=1, argv=0x000000016fdfb450, io=4308334032) at io.c:13497:5
frame #36: 0x00000001003c0004 miniruby`ractor_safe_call_cfunc_m1(recv=4308334032, argc=1, argv=0x000000016fdfb450, func=(miniruby`rb_io_set_encoding at io.c:13487)) at vm_insnhelper.c:3271:12
...
frame #43: 0x0000000100390b08 miniruby`rb_funcall(recv=4308334032, mid=16593, n=1) at vm_eval.c:1137:12
frame #44: 0x00000001002a43d8 miniruby`load_file_internal(argp_v=6171899936) at ruby.c:2500:5
...
```
2023-08-01 23:53:45 +03:00
|
|
|
if (cfp && VM_FRAME_TYPE(cfp) != VM_FRAME_MAGIC_DUMMY) {
|
|
|
|
rb_ivar_set(exc, id_iseq, rb_iseqw_new(cfp->iseq));
|
|
|
|
}
|
2018-04-12 06:48:48 +03:00
|
|
|
return exc;
|
|
|
|
}
|
2018-01-26 13:55:47 +03:00
|
|
|
|
2003-12-29 06:56:22 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2018-12-30 02:40:15 +03:00
|
|
|
* NameError.new(msg=nil, name=nil, receiver: nil) -> name_error
|
2003-12-29 06:56:22 +03:00
|
|
|
*
|
|
|
|
* Construct a new NameError exception. If given the <i>name</i>
|
2019-03-22 14:04:59 +03:00
|
|
|
* parameter may subsequently be examined using the NameError#name
|
2018-12-30 02:40:15 +03:00
|
|
|
* method. <i>receiver</i> parameter allows to pass object in
|
|
|
|
* context of which the error happened. Example:
|
|
|
|
*
|
|
|
|
* [1, 2, 3].method(:rject) # NameError with name "rject" and receiver: Array
|
|
|
|
* [1, 2, 3].singleton_method(:rject) # NameError with name "rject" and receiver: [1, 2, 3]
|
2003-12-29 06:56:22 +03:00
|
|
|
*/
|
|
|
|
|
2003-05-20 05:51:32 +04:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
name_err_initialize(int argc, VALUE *argv, VALUE self)
|
2018-01-26 13:55:47 +03:00
|
|
|
{
|
|
|
|
ID keywords[1];
|
2018-04-12 06:48:48 +03:00
|
|
|
VALUE values[numberof(keywords)], name, options;
|
2003-11-04 12:13:57 +03:00
|
|
|
|
2018-04-12 06:48:48 +03:00
|
|
|
argc = rb_scan_args(argc, argv, "*:", NULL, &options);
|
2018-01-26 13:55:47 +03:00
|
|
|
keywords[0] = id_receiver;
|
|
|
|
rb_get_kwargs(options, keywords, 0, numberof(values), values);
|
2003-11-16 02:45:26 +03:00
|
|
|
name = (argc > 1) ? argv[--argc] : Qnil;
|
2005-05-14 18:59:53 +04:00
|
|
|
rb_call_super(argc, argv);
|
2018-04-12 06:48:48 +03:00
|
|
|
name_err_init_attr(self, values[0], name);
|
2003-05-20 05:51:32 +04:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2019-11-18 06:13:08 +03:00
|
|
|
static VALUE rb_name_err_mesg_new(VALUE mesg, VALUE recv, VALUE method);
|
|
|
|
|
2018-04-12 06:48:48 +03:00
|
|
|
static VALUE
|
|
|
|
name_err_init(VALUE exc, VALUE mesg, VALUE recv, VALUE method)
|
|
|
|
{
|
|
|
|
exc_init(exc, rb_name_err_mesg_new(mesg, recv, method));
|
|
|
|
return name_err_init_attr(exc, recv, method);
|
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
|
|
|
rb_name_err_new(VALUE mesg, VALUE recv, VALUE method)
|
|
|
|
{
|
|
|
|
VALUE exc = rb_obj_alloc(rb_eNameError);
|
|
|
|
return name_err_init(exc, mesg, recv, method);
|
|
|
|
}
|
|
|
|
|
2003-12-29 06:56:22 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:31:22 +04:00
|
|
|
* name_error.name -> string or nil
|
2003-12-29 06:56:22 +03:00
|
|
|
*
|
|
|
|
* Return the name associated with this NameError exception.
|
|
|
|
*/
|
|
|
|
|
2001-07-02 12:46:28 +04:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
name_err_name(VALUE self)
|
2001-07-02 12:46:28 +04:00
|
|
|
{
|
2015-02-16 06:58:28 +03:00
|
|
|
return rb_attr_get(self, id_name);
|
2003-05-20 05:51:32 +04:00
|
|
|
}
|
|
|
|
|
2015-12-08 08:27:10 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* name_error.local_variables -> array
|
|
|
|
*
|
|
|
|
* Return a list of the local variable names defined where this
|
|
|
|
* NameError exception was raised.
|
|
|
|
*
|
|
|
|
* Internal use only.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
name_err_local_variables(VALUE self)
|
|
|
|
{
|
|
|
|
VALUE vars = rb_attr_get(self, id_local_variables);
|
|
|
|
|
|
|
|
if (NIL_P(vars)) {
|
|
|
|
VALUE iseqw = rb_attr_get(self, id_iseq);
|
|
|
|
if (!NIL_P(iseqw)) vars = rb_iseqw_local_variables(iseqw);
|
|
|
|
if (NIL_P(vars)) vars = rb_ary_new();
|
|
|
|
rb_ivar_set(self, id_local_variables, vars);
|
|
|
|
}
|
|
|
|
return vars;
|
|
|
|
}
|
|
|
|
|
2018-04-12 06:48:48 +03:00
|
|
|
static VALUE
|
|
|
|
nometh_err_init_attr(VALUE exc, VALUE args, int priv)
|
|
|
|
{
|
|
|
|
rb_ivar_set(exc, id_args, args);
|
2021-08-02 06:06:44 +03:00
|
|
|
rb_ivar_set(exc, id_private_call_p, RBOOL(priv));
|
2018-04-12 06:48:48 +03:00
|
|
|
return exc;
|
|
|
|
}
|
2018-01-26 13:55:47 +03:00
|
|
|
|
2003-12-29 06:56:22 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2018-12-30 02:40:15 +03:00
|
|
|
* NoMethodError.new(msg=nil, name=nil, args=nil, private=false, receiver: nil) -> no_method_error
|
2003-12-29 06:56:22 +03:00
|
|
|
*
|
2005-03-18 06:17:27 +03:00
|
|
|
* Construct a NoMethodError exception for a method of the given name
|
2003-12-29 06:56:22 +03:00
|
|
|
* called with the given arguments. The name may be accessed using
|
|
|
|
* the <code>#name</code> method on the resulting object, and the
|
|
|
|
* arguments using the <code>#args</code> method.
|
2018-12-30 02:40:15 +03:00
|
|
|
*
|
|
|
|
* If <i>private</i> argument were passed, it designates method was
|
|
|
|
* attempted to call in private context, and can be accessed with
|
|
|
|
* <code>#private_call?</code> method.
|
|
|
|
*
|
|
|
|
* <i>receiver</i> argument stores an object whose method was called.
|
2003-12-29 06:56:22 +03:00
|
|
|
*/
|
|
|
|
|
2003-05-20 05:51:32 +04:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
nometh_err_initialize(int argc, VALUE *argv, VALUE self)
|
2018-01-26 13:55:47 +03:00
|
|
|
{
|
2018-04-12 06:48:48 +03:00
|
|
|
int priv;
|
|
|
|
VALUE args, options;
|
2018-01-26 13:55:47 +03:00
|
|
|
argc = rb_scan_args(argc, argv, "*:", NULL, &options);
|
2018-04-12 06:48:48 +03:00
|
|
|
priv = (argc > 3) && (--argc, RTEST(argv[argc]));
|
|
|
|
args = (argc > 2) ? argv[--argc] : Qnil;
|
|
|
|
if (!NIL_P(options)) argv[argc++] = options;
|
Make rb_scan_args handle keywords more similar to Ruby methods (#2460)
Cfuncs that use rb_scan_args with the : entry suffer similar keyword
argument separation issues that Ruby methods suffer if the cfuncs
accept optional or variable arguments.
This makes the following changes to : handling.
* Treats as **kw, prompting keyword argument separation warnings
if called with a positional hash.
* Do not look for an option hash if empty keywords are provided.
For backwards compatibility, treat an empty keyword splat as a empty
mandatory positional hash argument, but emit a a warning, as this
behavior will be removed in Ruby 3. The argument number check
needs to be moved lower so it can correctly handle an empty
positional argument being added.
* If the last argument is nil and it is necessary to treat it as an option
hash in order to make sure all arguments are processed, continue to
treat the last argument as the option hash. Emit a warning in this case,
as this behavior will be removed in Ruby 3.
* If splitting the keyword hash into two hashes, issue a warning, as we
will not be splitting hashes in Ruby 3.
* If the keyword argument is required to fill a mandatory positional
argument, continue to do so, but emit a warning as this behavior will
be going away in Ruby 3.
* If keyword arguments are provided and the last argument is not a hash,
that indicates something wrong. This can happen if a cfunc is calling
rb_scan_args multiple times, and providing arguments that were not
passed to it from Ruby. Callers need to switch to the new
rb_scan_args_kw function, which allows passing of whether keywords
were provided.
This commit fixes all warnings caused by the changes above.
It switches some function calls to *_kw versions with appropriate
kw_splat flags. If delegating arguments, RB_PASS_CALLED_KEYWORDS
is used. If creating new arguments, RB_PASS_KEYWORDS is used if
the last argument is a hash to be treated as keywords.
In open_key_args in io.c, use rb_scan_args_kw.
In this case, the arguments provided come from another C
function, not Ruby. The last argument may or may not be a hash,
so we can't set keyword argument mode. However, if it is a
hash, we don't want to warn when treating it as keywords.
In Ruby files, make sure to appropriately use keyword splats
or literal keywords when calling Cfuncs that now issue keyword
argument separation warnings through rb_scan_args. Also, make
sure not to pass nil in place of an option hash.
Work around Kernel#warn warnings due to problems in the Rubygems
override of the method. There is an open pull request to fix
these issues in Rubygems, but part of the Rubygems tests for
their override fail on ruby-head due to rb_scan_args not
recognizing empty keyword splats, which this commit fixes.
Implementation wise, adding rb_scan_args_kw is kind of a pain,
because rb_scan_args takes a variable number of arguments.
In order to not duplicate all the code, the function internals need
to be split into two functions taking a va_list, and to avoid passing
in a ton of arguments, a single struct argument is used to handle
the variables previously local to the function.
2019-09-25 21:18:49 +03:00
|
|
|
rb_call_super_kw(argc, argv, RB_PASS_CALLED_KEYWORDS);
|
2018-04-12 06:48:48 +03:00
|
|
|
return nometh_err_init_attr(self, args, priv);
|
2018-01-26 13:55:47 +03:00
|
|
|
}
|
|
|
|
|
2018-04-12 06:48:48 +03:00
|
|
|
VALUE
|
|
|
|
rb_nomethod_err_new(VALUE mesg, VALUE recv, VALUE method, VALUE args, int priv)
|
2003-05-20 05:51:32 +04:00
|
|
|
{
|
2018-04-12 06:48:48 +03:00
|
|
|
VALUE exc = rb_obj_alloc(rb_eNoMethodError);
|
|
|
|
name_err_init(exc, mesg, recv, method);
|
|
|
|
return nometh_err_init_attr(exc, args, priv);
|
2001-07-02 12:46:28 +04:00
|
|
|
}
|
|
|
|
|
2023-11-21 15:07:53 +03:00
|
|
|
typedef struct name_error_message_struct {
|
|
|
|
VALUE mesg;
|
|
|
|
VALUE recv;
|
|
|
|
VALUE name;
|
|
|
|
} name_error_message_t;
|
2009-09-09 06:55:09 +04:00
|
|
|
|
2004-01-17 17:58:57 +03:00
|
|
|
static void
|
2009-09-09 06:55:09 +04:00
|
|
|
name_err_mesg_mark(void *p)
|
2004-01-17 17:58:57 +03:00
|
|
|
{
|
2023-11-21 15:07:53 +03:00
|
|
|
name_error_message_t *ptr = (name_error_message_t *)p;
|
|
|
|
rb_gc_mark_movable(ptr->mesg);
|
|
|
|
rb_gc_mark_movable(ptr->recv);
|
|
|
|
rb_gc_mark_movable(ptr->name);
|
2004-01-17 17:58:57 +03:00
|
|
|
}
|
|
|
|
|
2023-11-21 15:07:53 +03:00
|
|
|
static void
|
|
|
|
name_err_mesg_update(void *p)
|
2009-09-09 06:55:09 +04:00
|
|
|
{
|
2023-11-21 15:07:53 +03:00
|
|
|
name_error_message_t *ptr = (name_error_message_t *)p;
|
|
|
|
ptr->mesg = rb_gc_location(ptr->mesg);
|
|
|
|
ptr->recv = rb_gc_location(ptr->recv);
|
|
|
|
ptr->name = rb_gc_location(ptr->name);
|
2009-09-09 06:55:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static const rb_data_type_t name_err_mesg_data_type = {
|
|
|
|
"name_err_mesg",
|
2010-07-18 11:31:54 +04:00
|
|
|
{
|
|
|
|
name_err_mesg_mark,
|
2023-11-21 15:07:53 +03:00
|
|
|
RUBY_TYPED_DEFAULT_FREE,
|
|
|
|
NULL, // No external memory to report,
|
|
|
|
name_err_mesg_update,
|
2010-07-18 11:31:54 +04:00
|
|
|
},
|
2023-11-21 15:07:53 +03:00
|
|
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
|
2009-09-09 06:55:09 +04:00
|
|
|
};
|
|
|
|
|
2004-01-18 17:16:47 +03:00
|
|
|
/* :nodoc: */
|
2019-11-18 06:13:08 +03:00
|
|
|
static VALUE
|
2023-11-21 15:07:53 +03:00
|
|
|
rb_name_err_mesg_init(VALUE klass, VALUE mesg, VALUE recv, VALUE name)
|
2004-01-17 17:58:57 +03:00
|
|
|
{
|
2023-11-21 15:07:53 +03:00
|
|
|
name_error_message_t *message;
|
|
|
|
VALUE result = TypedData_Make_Struct(klass, name_error_message_t, &name_err_mesg_data_type, message);
|
|
|
|
RB_OBJ_WRITE(result, &message->mesg, mesg);
|
|
|
|
RB_OBJ_WRITE(result, &message->recv, recv);
|
|
|
|
RB_OBJ_WRITE(result, &message->name, name);
|
2010-06-05 06:01:29 +04:00
|
|
|
return result;
|
2004-01-17 17:58:57 +03:00
|
|
|
}
|
|
|
|
|
2021-02-01 12:01:10 +03:00
|
|
|
/* :nodoc: */
|
|
|
|
static VALUE
|
|
|
|
rb_name_err_mesg_new(VALUE mesg, VALUE recv, VALUE method)
|
|
|
|
{
|
|
|
|
return rb_name_err_mesg_init(rb_cNameErrorMesg, mesg, recv, method);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* :nodoc: */
|
|
|
|
static VALUE
|
|
|
|
name_err_mesg_alloc(VALUE klass)
|
|
|
|
{
|
|
|
|
return rb_name_err_mesg_init(klass, Qnil, Qnil, Qnil);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* :nodoc: */
|
|
|
|
static VALUE
|
|
|
|
name_err_mesg_init_copy(VALUE obj1, VALUE obj2)
|
|
|
|
{
|
|
|
|
if (obj1 == obj2) return obj1;
|
|
|
|
rb_obj_init_copy(obj1, obj2);
|
|
|
|
|
2023-11-21 15:07:53 +03:00
|
|
|
name_error_message_t *ptr1, *ptr2;
|
|
|
|
TypedData_Get_Struct(obj1, name_error_message_t, &name_err_mesg_data_type, ptr1);
|
|
|
|
TypedData_Get_Struct(obj2, name_error_message_t, &name_err_mesg_data_type, ptr2);
|
|
|
|
|
|
|
|
RB_OBJ_WRITE(obj1, &ptr1->mesg, ptr2->mesg);
|
|
|
|
RB_OBJ_WRITE(obj1, &ptr1->recv, ptr2->recv);
|
|
|
|
RB_OBJ_WRITE(obj1, &ptr1->name, ptr2->name);
|
2021-02-01 12:01:10 +03:00
|
|
|
return obj1;
|
|
|
|
}
|
|
|
|
|
2004-08-28 18:14:11 +04:00
|
|
|
/* :nodoc: */
|
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
name_err_mesg_equal(VALUE obj1, VALUE obj2)
|
2004-08-28 18:14:11 +04:00
|
|
|
{
|
|
|
|
if (obj1 == obj2) return Qtrue;
|
2023-11-21 15:07:53 +03:00
|
|
|
|
2004-08-28 18:14:11 +04:00
|
|
|
if (rb_obj_class(obj2) != rb_cNameErrorMesg)
|
|
|
|
return Qfalse;
|
|
|
|
|
2023-11-21 15:07:53 +03:00
|
|
|
name_error_message_t *ptr1, *ptr2;
|
|
|
|
TypedData_Get_Struct(obj1, name_error_message_t, &name_err_mesg_data_type, ptr1);
|
|
|
|
TypedData_Get_Struct(obj2, name_error_message_t, &name_err_mesg_data_type, ptr2);
|
|
|
|
|
|
|
|
if (!rb_equal(ptr1->mesg, ptr2->mesg)) return Qfalse;
|
|
|
|
if (!rb_equal(ptr1->recv, ptr2->recv)) return Qfalse;
|
|
|
|
if (!rb_equal(ptr1->name, ptr2->name)) return Qfalse;
|
2004-08-28 18:14:11 +04:00
|
|
|
return Qtrue;
|
|
|
|
}
|
|
|
|
|
2020-05-04 17:56:45 +03:00
|
|
|
/* :nodoc: */
|
|
|
|
static VALUE
|
|
|
|
name_err_mesg_receiver_name(VALUE obj)
|
|
|
|
{
|
|
|
|
if (RB_SPECIAL_CONST_P(obj)) return Qundef;
|
|
|
|
if (RB_BUILTIN_TYPE(obj) == T_MODULE || RB_BUILTIN_TYPE(obj) == T_CLASS) {
|
|
|
|
return rb_check_funcall(obj, rb_intern("name"), 0, 0);
|
|
|
|
}
|
|
|
|
return Qundef;
|
|
|
|
}
|
|
|
|
|
2004-01-18 17:16:47 +03:00
|
|
|
/* :nodoc: */
|
2004-01-17 17:58:57 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
name_err_mesg_to_str(VALUE obj)
|
2004-01-17 17:58:57 +03:00
|
|
|
{
|
2023-11-21 15:07:53 +03:00
|
|
|
name_error_message_t *ptr;
|
|
|
|
TypedData_Get_Struct(obj, name_error_message_t, &name_err_mesg_data_type, ptr);
|
2004-01-17 17:58:57 +03:00
|
|
|
|
2023-11-21 15:07:53 +03:00
|
|
|
VALUE mesg = ptr->mesg;
|
2004-01-17 17:58:57 +03:00
|
|
|
if (NIL_P(mesg)) return Qnil;
|
|
|
|
else {
|
2023-01-30 12:07:47 +03:00
|
|
|
struct RString s_str, c_str, d_str;
|
2022-12-16 01:31:27 +03:00
|
|
|
VALUE c, s, d = 0, args[4], c2;
|
|
|
|
int state = 0;
|
2015-10-23 17:27:37 +03:00
|
|
|
rb_encoding *usascii = rb_usascii_encoding();
|
2004-01-17 17:58:57 +03:00
|
|
|
|
2015-10-23 17:27:37 +03:00
|
|
|
#define FAKE_CSTR(v, str) rb_setup_fake_str((v), (str), rb_strlen_lit(str), usascii)
|
2022-12-16 01:31:27 +03:00
|
|
|
c = s = FAKE_CSTR(&s_str, "");
|
2023-11-21 15:07:53 +03:00
|
|
|
obj = ptr->recv;
|
2012-04-13 19:34:34 +04:00
|
|
|
switch (obj) {
|
|
|
|
case Qnil:
|
2022-12-16 01:31:27 +03:00
|
|
|
c = d = FAKE_CSTR(&d_str, "nil");
|
2004-01-17 17:58:57 +03:00
|
|
|
break;
|
2012-04-13 19:34:34 +04:00
|
|
|
case Qtrue:
|
2022-12-16 01:31:27 +03:00
|
|
|
c = d = FAKE_CSTR(&d_str, "true");
|
2004-01-17 17:58:57 +03:00
|
|
|
break;
|
2012-04-13 19:34:34 +04:00
|
|
|
case Qfalse:
|
2022-12-16 01:31:27 +03:00
|
|
|
c = d = FAKE_CSTR(&d_str, "false");
|
2004-01-17 17:58:57 +03:00
|
|
|
break;
|
|
|
|
default:
|
2022-12-16 01:31:27 +03:00
|
|
|
if (strstr(RSTRING_PTR(mesg), "%2$s")) {
|
|
|
|
d = rb_protect(name_err_mesg_receiver_name, obj, &state);
|
|
|
|
if (state || NIL_OR_UNDEF_P(d))
|
|
|
|
d = rb_protect(rb_inspect, obj, &state);
|
|
|
|
if (state) {
|
|
|
|
rb_set_errinfo(Qnil);
|
|
|
|
}
|
|
|
|
d = rb_check_string_type(d);
|
|
|
|
if (NIL_P(d)) {
|
|
|
|
d = rb_any_to_s(obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!RB_SPECIAL_CONST_P(obj)) {
|
|
|
|
switch (RB_BUILTIN_TYPE(obj)) {
|
2023-02-20 04:50:49 +03:00
|
|
|
case T_MODULE:
|
|
|
|
s = FAKE_CSTR(&s_str, "module ");
|
|
|
|
c = obj;
|
|
|
|
break;
|
|
|
|
case T_CLASS:
|
|
|
|
s = FAKE_CSTR(&s_str, "class ");
|
|
|
|
c = obj;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
goto object;
|
2022-12-16 01:31:27 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
VALUE klass;
|
2023-02-20 04:50:49 +03:00
|
|
|
object:
|
2022-12-16 01:31:27 +03:00
|
|
|
klass = CLASS_OF(obj);
|
2024-03-06 19:04:22 +03:00
|
|
|
if (RB_TYPE_P(klass, T_CLASS) && RCLASS_SINGLETON_P(klass)) {
|
2023-01-24 11:40:57 +03:00
|
|
|
s = FAKE_CSTR(&s_str, "");
|
2023-01-30 12:07:47 +03:00
|
|
|
if (obj == rb_vm_top_self()) {
|
|
|
|
c = FAKE_CSTR(&c_str, "main");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
c = rb_any_to_s(obj);
|
|
|
|
}
|
2023-01-24 11:40:57 +03:00
|
|
|
break;
|
2022-12-16 01:31:27 +03:00
|
|
|
}
|
|
|
|
else {
|
2023-01-24 11:40:57 +03:00
|
|
|
s = FAKE_CSTR(&s_str, "an instance of ");
|
|
|
|
c = rb_class_real(klass);
|
2022-12-16 01:31:27 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
c2 = rb_protect(name_err_mesg_receiver_name, c, &state);
|
|
|
|
if (state || NIL_OR_UNDEF_P(c2))
|
|
|
|
c2 = rb_protect(rb_inspect, c, &state);
|
2021-03-28 02:47:42 +03:00
|
|
|
if (state) {
|
2011-12-13 18:50:12 +04:00
|
|
|
rb_set_errinfo(Qnil);
|
2021-03-28 02:47:42 +03:00
|
|
|
}
|
2022-12-16 01:31:27 +03:00
|
|
|
c2 = rb_check_string_type(c2);
|
|
|
|
if (NIL_P(c2)) {
|
|
|
|
c2 = rb_any_to_s(c);
|
2004-01-17 17:58:57 +03:00
|
|
|
}
|
2022-12-16 01:31:27 +03:00
|
|
|
c = c2;
|
2004-01-17 17:58:57 +03:00
|
|
|
break;
|
|
|
|
}
|
2023-11-21 15:07:53 +03:00
|
|
|
args[0] = rb_obj_as_string(ptr->name);
|
2015-10-23 15:10:40 +03:00
|
|
|
args[1] = d;
|
|
|
|
args[2] = s;
|
|
|
|
args[3] = c;
|
|
|
|
mesg = rb_str_format(4, args, mesg);
|
2004-01-17 17:58:57 +03:00
|
|
|
}
|
|
|
|
return mesg;
|
|
|
|
}
|
|
|
|
|
2012-12-24 19:58:15 +04:00
|
|
|
/* :nodoc: */
|
|
|
|
static VALUE
|
|
|
|
name_err_mesg_dump(VALUE obj, VALUE limit)
|
|
|
|
{
|
|
|
|
return name_err_mesg_to_str(obj);
|
|
|
|
}
|
|
|
|
|
2004-01-18 17:16:47 +03:00
|
|
|
/* :nodoc: */
|
2004-01-17 17:58:57 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
name_err_mesg_load(VALUE klass, VALUE str)
|
2004-01-17 17:58:57 +03:00
|
|
|
{
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2015-06-18 07:32:50 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* name_error.receiver -> object
|
|
|
|
*
|
|
|
|
* Return the receiver associated with this NameError exception.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
name_err_receiver(VALUE self)
|
|
|
|
{
|
2023-11-21 15:07:53 +03:00
|
|
|
VALUE recv = rb_ivar_lookup(self, id_recv, Qundef);
|
2022-11-15 07:24:08 +03:00
|
|
|
if (!UNDEF_P(recv)) return recv;
|
2015-10-28 09:36:13 +03:00
|
|
|
|
2023-11-21 15:07:53 +03:00
|
|
|
VALUE mesg = rb_attr_get(self, id_mesg);
|
2015-06-23 08:32:52 +03:00
|
|
|
if (!rb_typeddata_is_kind_of(mesg, &name_err_mesg_data_type)) {
|
|
|
|
rb_raise(rb_eArgError, "no receiver is available");
|
|
|
|
}
|
2023-11-21 15:07:53 +03:00
|
|
|
|
|
|
|
name_error_message_t *ptr;
|
|
|
|
TypedData_Get_Struct(mesg, name_error_message_t, &name_err_mesg_data_type, ptr);
|
|
|
|
return ptr->recv;
|
2015-06-18 07:32:50 +03:00
|
|
|
}
|
|
|
|
|
2003-12-29 06:56:22 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:31:22 +04:00
|
|
|
* no_method_error.args -> obj
|
2003-12-29 06:56:22 +03:00
|
|
|
*
|
|
|
|
* Return the arguments passed in as the third parameter to
|
|
|
|
* the constructor.
|
|
|
|
*/
|
|
|
|
|
2001-07-02 12:46:28 +04:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
nometh_err_args(VALUE self)
|
2001-07-02 12:46:28 +04:00
|
|
|
{
|
2015-02-16 06:58:28 +03:00
|
|
|
return rb_attr_get(self, id_args);
|
2001-07-02 12:46:28 +04:00
|
|
|
}
|
|
|
|
|
2018-02-23 05:18:52 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* no_method_error.private_call? -> true or false
|
|
|
|
*
|
|
|
|
* Return true if the caused method was called as private.
|
|
|
|
*/
|
|
|
|
|
2016-02-28 07:41:38 +03:00
|
|
|
static VALUE
|
|
|
|
nometh_err_private_call_p(VALUE self)
|
|
|
|
{
|
|
|
|
return rb_attr_get(self, id_private_call_p);
|
|
|
|
}
|
|
|
|
|
2002-01-04 17:15:33 +03:00
|
|
|
void
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_invalid_str(const char *str, const char *type)
|
2002-01-04 17:15:33 +03:00
|
|
|
{
|
2012-05-24 20:15:42 +04:00
|
|
|
VALUE s = rb_str_new2(str);
|
2002-01-04 17:15:33 +03:00
|
|
|
|
2012-05-24 20:15:42 +04:00
|
|
|
rb_raise(rb_eArgError, "invalid value for %s: %+"PRIsVALUE, type, s);
|
2002-01-04 17:15:33 +03:00
|
|
|
}
|
|
|
|
|
2017-12-19 07:57:20 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* key_error.receiver -> object
|
|
|
|
*
|
|
|
|
* Return the receiver associated with this KeyError exception.
|
|
|
|
*/
|
|
|
|
|
2019-12-14 18:18:09 +03:00
|
|
|
static VALUE
|
|
|
|
key_err_receiver(VALUE self)
|
|
|
|
{
|
|
|
|
VALUE recv;
|
|
|
|
|
|
|
|
recv = rb_ivar_lookup(self, id_receiver, Qundef);
|
2022-11-15 07:24:08 +03:00
|
|
|
if (!UNDEF_P(recv)) return recv;
|
2019-12-14 18:18:09 +03:00
|
|
|
rb_raise(rb_eArgError, "no receiver is available");
|
|
|
|
}
|
2017-09-18 11:05:53 +03:00
|
|
|
|
2017-12-19 07:57:20 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* key_error.key -> object
|
|
|
|
*
|
|
|
|
* Return the key caused this KeyError exception.
|
|
|
|
*/
|
|
|
|
|
2017-09-18 11:05:53 +03:00
|
|
|
static VALUE
|
|
|
|
key_err_key(VALUE self)
|
|
|
|
{
|
|
|
|
VALUE key;
|
|
|
|
|
|
|
|
key = rb_ivar_lookup(self, id_key, Qundef);
|
2022-11-15 07:24:08 +03:00
|
|
|
if (!UNDEF_P(key)) return key;
|
2017-09-18 11:05:53 +03:00
|
|
|
rb_raise(rb_eArgError, "no key is available");
|
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
|
|
|
rb_key_err_new(VALUE mesg, VALUE recv, VALUE key)
|
|
|
|
{
|
|
|
|
VALUE exc = rb_obj_alloc(rb_eKeyError);
|
|
|
|
rb_ivar_set(exc, id_mesg, mesg);
|
|
|
|
rb_ivar_set(exc, id_bt, Qnil);
|
|
|
|
rb_ivar_set(exc, id_key, key);
|
|
|
|
rb_ivar_set(exc, id_receiver, recv);
|
|
|
|
return exc;
|
|
|
|
}
|
|
|
|
|
2018-01-26 07:51:14 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* KeyError.new(message=nil, receiver: nil, key: nil) -> key_error
|
|
|
|
*
|
|
|
|
* Construct a new +KeyError+ exception with the given message,
|
|
|
|
* receiver and key.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
key_err_initialize(int argc, VALUE *argv, VALUE self)
|
|
|
|
{
|
|
|
|
VALUE options;
|
|
|
|
|
2018-01-26 13:55:45 +03:00
|
|
|
rb_call_super(rb_scan_args(argc, argv, "01:", NULL, &options), argv);
|
2018-01-26 07:51:14 +03:00
|
|
|
|
|
|
|
if (!NIL_P(options)) {
|
2018-01-26 08:34:18 +03:00
|
|
|
ID keywords[2];
|
2018-01-26 13:55:45 +03:00
|
|
|
VALUE values[numberof(keywords)];
|
|
|
|
int i;
|
2018-01-26 08:34:18 +03:00
|
|
|
keywords[0] = id_receiver;
|
|
|
|
keywords[1] = id_key;
|
2018-01-26 13:55:45 +03:00
|
|
|
rb_get_kwargs(options, keywords, 0, numberof(values), values);
|
|
|
|
for (i = 0; i < numberof(values); ++i) {
|
2022-11-15 07:24:08 +03:00
|
|
|
if (!UNDEF_P(values[i])) {
|
2018-01-26 13:55:45 +03:00
|
|
|
rb_ivar_set(self, keywords[i], values[i]);
|
|
|
|
}
|
2018-01-26 07:51:14 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2021-08-15 03:38:24 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* no_matching_pattern_key_error.matchee -> object
|
|
|
|
*
|
|
|
|
* Return the matchee associated with this NoMatchingPatternKeyError exception.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
no_matching_pattern_key_err_matchee(VALUE self)
|
|
|
|
{
|
|
|
|
VALUE matchee;
|
|
|
|
|
|
|
|
matchee = rb_ivar_lookup(self, id_matchee, Qundef);
|
2022-11-15 07:24:08 +03:00
|
|
|
if (!UNDEF_P(matchee)) return matchee;
|
2021-08-15 03:38:24 +03:00
|
|
|
rb_raise(rb_eArgError, "no matchee is available");
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* no_matching_pattern_key_error.key -> object
|
|
|
|
*
|
|
|
|
* Return the key caused this NoMatchingPatternKeyError exception.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
no_matching_pattern_key_err_key(VALUE self)
|
|
|
|
{
|
|
|
|
VALUE key;
|
|
|
|
|
|
|
|
key = rb_ivar_lookup(self, id_key, Qundef);
|
2022-11-15 07:24:08 +03:00
|
|
|
if (!UNDEF_P(key)) return key;
|
2021-08-15 03:38:24 +03:00
|
|
|
rb_raise(rb_eArgError, "no key is available");
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* NoMatchingPatternKeyError.new(message=nil, matchee: nil, key: nil) -> no_matching_pattern_key_error
|
|
|
|
*
|
|
|
|
* Construct a new +NoMatchingPatternKeyError+ exception with the given message,
|
|
|
|
* matchee and key.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
no_matching_pattern_key_err_initialize(int argc, VALUE *argv, VALUE self)
|
|
|
|
{
|
|
|
|
VALUE options;
|
|
|
|
|
|
|
|
rb_call_super(rb_scan_args(argc, argv, "01:", NULL, &options), argv);
|
|
|
|
|
|
|
|
if (!NIL_P(options)) {
|
|
|
|
ID keywords[2];
|
|
|
|
VALUE values[numberof(keywords)];
|
|
|
|
int i;
|
|
|
|
keywords[0] = id_matchee;
|
|
|
|
keywords[1] = id_key;
|
|
|
|
rb_get_kwargs(options, keywords, 0, numberof(values), values);
|
|
|
|
for (i = 0; i < numberof(values); ++i) {
|
2022-11-15 07:24:08 +03:00
|
|
|
if (!UNDEF_P(values[i])) {
|
2021-08-15 03:38:24 +03:00
|
|
|
rb_ivar_set(self, keywords[i], values[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-04-20 09:52:30 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* SyntaxError.new([msg]) -> syntax_error
|
|
|
|
*
|
|
|
|
* Construct a SyntaxError exception.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
syntax_error_initialize(int argc, VALUE *argv, VALUE self)
|
|
|
|
{
|
|
|
|
VALUE mesg;
|
|
|
|
if (argc == 0) {
|
2018-10-13 12:59:22 +03:00
|
|
|
mesg = rb_fstring_lit("compile error");
|
2016-04-20 09:52:30 +03:00
|
|
|
argc = 1;
|
|
|
|
argv = &mesg;
|
|
|
|
}
|
|
|
|
return rb_call_super(argc, argv);
|
|
|
|
}
|
|
|
|
|
2022-11-20 16:59:52 +03:00
|
|
|
static VALUE
|
|
|
|
syntax_error_with_path(VALUE exc, VALUE path, VALUE *mesg, rb_encoding *enc)
|
|
|
|
{
|
|
|
|
if (NIL_P(exc)) {
|
|
|
|
*mesg = rb_enc_str_new(0, 0, enc);
|
|
|
|
exc = rb_class_new_instance(1, mesg, rb_eSyntaxError);
|
|
|
|
rb_ivar_set(exc, id_i_path, path);
|
|
|
|
}
|
|
|
|
else {
|
2024-05-26 14:14:18 +03:00
|
|
|
VALUE old_path = rb_attr_get(exc, id_i_path);
|
|
|
|
if (old_path != path) {
|
2024-05-30 13:05:52 +03:00
|
|
|
if (rb_str_equal(path, old_path)) {
|
|
|
|
rb_raise(rb_eArgError, "SyntaxError#path changed: %+"PRIsVALUE" (%p->%p)",
|
|
|
|
old_path, (void *)old_path, (void *)path);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rb_raise(rb_eArgError, "SyntaxError#path changed: %+"PRIsVALUE"(%s%s)->%+"PRIsVALUE"(%s)",
|
|
|
|
old_path, rb_enc_name(rb_enc_get(old_path)),
|
|
|
|
(FL_TEST(old_path, RSTRING_FSTR) ? ":FSTR" : ""),
|
|
|
|
path, rb_enc_name(rb_enc_get(path)));
|
|
|
|
}
|
2022-11-20 16:59:52 +03:00
|
|
|
}
|
|
|
|
VALUE s = *mesg = rb_attr_get(exc, idMesg);
|
|
|
|
if (RSTRING_LEN(s) > 0 && *(RSTRING_END(s)-1) != '\n')
|
|
|
|
rb_str_cat_cstr(s, "\n");
|
|
|
|
}
|
|
|
|
return exc;
|
|
|
|
}
|
|
|
|
|
2009-02-22 17:23:33 +03:00
|
|
|
/*
|
2003-12-21 10:28:54 +03:00
|
|
|
* Document-module: Errno
|
2024-06-05 23:27:00 +03:00
|
|
|
|
|
|
|
* When an operating system encounters an error,
|
|
|
|
* it typically reports the error as an integer error code:
|
|
|
|
*
|
|
|
|
* $ ls nosuch.txt
|
|
|
|
* ls: cannot access 'nosuch.txt': No such file or directory
|
|
|
|
* $ echo $? # Code for last error.
|
|
|
|
* 2
|
|
|
|
*
|
|
|
|
* When the Ruby interpreter interacts with the operating system
|
|
|
|
* and receives such an error code (e.g., +2+),
|
|
|
|
* it maps the code to a particular Ruby exception class (e.g., +Errno::ENOENT+):
|
|
|
|
*
|
|
|
|
* File.open('nosuch.txt')
|
|
|
|
* # => No such file or directory @ rb_sysopen - nosuch.txt (Errno::ENOENT)
|
|
|
|
*
|
|
|
|
* Each such class is:
|
|
|
|
*
|
|
|
|
* - A nested class in this module, +Errno+.
|
|
|
|
* - A subclass of class SystemCallError.
|
|
|
|
* - Associated with an error code.
|
|
|
|
*
|
|
|
|
* Thus:
|
2003-12-21 10:28:54 +03:00
|
|
|
*
|
2024-06-05 23:27:00 +03:00
|
|
|
* Errno::ENOENT.superclass # => SystemCallError
|
|
|
|
* Errno::ENOENT::Errno # => 2
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2024-06-05 23:27:00 +03:00
|
|
|
* The names of nested classes are returned by method +Errno.constants+:
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2024-06-05 23:27:00 +03:00
|
|
|
* Errno.constants.size # => 158
|
|
|
|
* Errno.constants.sort.take(5) # => [:E2BIG, :EACCES, :EADDRINUSE, :EADDRNOTAVAIL, :EADV]
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2024-06-05 23:27:00 +03:00
|
|
|
* As seen above, the error code associated with each class
|
|
|
|
* is available as the value of a constant;
|
|
|
|
* the value for a particular class may vary among operating systems.
|
|
|
|
* If the class is not needed for the particular operating system,
|
|
|
|
* the value is zero:
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2024-06-05 23:27:00 +03:00
|
|
|
* Errno::ENOENT::Errno # => 2
|
|
|
|
* Errno::ENOTCAPABLE::Errno # => 0
|
2003-12-21 10:28:54 +03:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2002-11-22 12:14:24 +03:00
|
|
|
static st_table *syserr_tbl;
|
1999-01-20 07:59:39 +03:00
|
|
|
|
2023-10-12 21:15:53 +03:00
|
|
|
void
|
|
|
|
rb_free_warning(void)
|
|
|
|
{
|
|
|
|
st_free_table(warning_categories.id2enum);
|
|
|
|
st_free_table(warning_categories.enum2id);
|
|
|
|
st_free_table(syserr_tbl);
|
|
|
|
}
|
|
|
|
|
2002-11-03 14:04:35 +03:00
|
|
|
static VALUE
|
2024-01-11 16:46:49 +03:00
|
|
|
setup_syserr(int n, const char *name)
|
2002-11-03 14:04:35 +03:00
|
|
|
{
|
2024-01-11 16:46:49 +03:00
|
|
|
VALUE error = rb_define_class_under(rb_mErrno, name, rb_eSystemCallError);
|
2013-04-09 00:27:01 +04:00
|
|
|
|
2024-01-11 16:46:49 +03:00
|
|
|
/* capture nonblock errnos for WaitReadable/WaitWritable subclasses */
|
|
|
|
switch (n) {
|
|
|
|
case EAGAIN:
|
|
|
|
rb_eEAGAIN = error;
|
2013-04-09 00:27:01 +04:00
|
|
|
|
2014-10-20 10:58:16 +04:00
|
|
|
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
|
2024-01-11 16:46:49 +03:00
|
|
|
break;
|
|
|
|
case EWOULDBLOCK:
|
2013-04-08 23:58:55 +04:00
|
|
|
#endif
|
|
|
|
|
2024-01-11 16:46:49 +03:00
|
|
|
rb_eEWOULDBLOCK = error;
|
|
|
|
break;
|
|
|
|
case EINPROGRESS:
|
|
|
|
rb_eEINPROGRESS = error;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
rb_define_const(error, "Errno", INT2NUM(n));
|
|
|
|
st_add_direct(syserr_tbl, n, (st_data_t)error);
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
set_syserr(int n, const char *name)
|
|
|
|
{
|
|
|
|
st_data_t error;
|
2013-04-09 00:27:01 +04:00
|
|
|
|
2024-01-11 16:46:49 +03:00
|
|
|
if (!st_lookup(syserr_tbl, n, &error)) {
|
|
|
|
return setup_syserr(n, name);
|
2002-11-03 14:04:35 +03:00
|
|
|
}
|
2003-01-23 06:39:25 +03:00
|
|
|
else {
|
2024-01-11 16:46:49 +03:00
|
|
|
VALUE errclass = (VALUE)error;
|
|
|
|
rb_define_const(rb_mErrno, name, errclass);
|
|
|
|
return errclass;
|
2003-01-23 06:39:25 +03:00
|
|
|
}
|
2002-11-03 14:04:35 +03:00
|
|
|
}
|
1998-01-16 15:13:05 +03:00
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
get_syserr(int n)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
* compile.c (iseq_build_body), error.c (set_syserr, get_syserr),
(syserr_initialize), gc.c (define_final, rb_gc_copy_finalizer),
(run_final), hash.c (rb_hash_aref, rb_hash_lookup2),
(rb_hash_fetch_m, rb_hash_clear, rb_hash_aset, eql_i),
iseq.c (iseq_load, iseq_data_to_ary), marshal.c (r_symlink),
thread.c (rb_thread_local_aref),
variable.c (generic_ivar_remove, ivar_get, rb_const_get_0),
(rb_cvar_get), vm.c (rb_vm_check_redefinition_opt_method),
vm_insnhelper.c (vm_get_ev_const), vm_method.c (remove_method),
ext/iconv/iconv.c (map_charset): use st_data_t.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29462 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2010-10-12 18:47:23 +04:00
|
|
|
st_data_t error;
|
2002-11-03 14:04:35 +03:00
|
|
|
|
|
|
|
if (!st_lookup(syserr_tbl, n, &error)) {
|
2024-01-11 16:46:49 +03:00
|
|
|
char name[DECIMAL_SIZE_OF(n) + sizeof("E-")];
|
2003-01-26 20:09:16 +03:00
|
|
|
|
2003-01-26 21:31:03 +03:00
|
|
|
snprintf(name, sizeof(name), "E%03d", n);
|
2024-01-11 16:46:49 +03:00
|
|
|
return setup_syserr(n, name);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2024-01-11 16:46:49 +03:00
|
|
|
return (VALUE)error;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2003-12-29 06:56:22 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:31:22 +04:00
|
|
|
* SystemCallError.new(msg, errno) -> system_call_error_subclass
|
2003-12-29 06:56:22 +03:00
|
|
|
*
|
2019-03-22 14:04:59 +03:00
|
|
|
* If _errno_ corresponds to a known system error code, constructs the
|
|
|
|
* appropriate Errno class for that error, otherwise constructs a
|
|
|
|
* generic SystemCallError object. The error number is subsequently
|
|
|
|
* available via the #errno method.
|
2003-12-29 06:56:22 +03:00
|
|
|
*/
|
|
|
|
|
2003-05-20 05:51:32 +04:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
syserr_initialize(int argc, VALUE *argv, VALUE self)
|
2003-05-20 05:51:32 +04:00
|
|
|
{
|
* sprintf.c (rb_str_format): allow %c to print one character
string (e.g. ?x).
* lib/tempfile.rb (Tempfile::make_tmpname): put dot between
basename and pid. [ruby-talk:196272]
* parse.y (do_block): remove -> style block.
* parse.y (parser_yylex): remove tLAMBDA_ARG.
* eval.c (rb_call0): binding for the return event hook should have
consistent scope. [ruby-core:07928]
* eval.c (proc_invoke): return behavior should depend whether it
is surrounded by a lambda or a mere block.
* eval.c (formal_assign): handles post splat arguments.
* eval.c (rb_call0): ditto.
* st.c (strhash): use FNV-1a hash.
* parse.y (parser_yylex): removed experimental ';;' terminator.
* eval.c (rb_node_arity): should be aware of post splat arguments.
* eval.c (rb_proc_arity): ditto.
* parse.y (f_args): syntax rule enhanced to support arguments
after the splat.
* parse.y (block_param): ditto for block parameters.
* parse.y (f_post_arg): mandatory formal arguments after the splat
argument.
* parse.y (new_args_gen): generate nodes for mandatory formal
arguments after the splat argument.
* eval.c (rb_eval): dispatch mandatory formal arguments after the
splat argument.
* parse.y (args): allow more than one splat in the argument list.
* parse.y (method_call): allow aref [] to accept all kind of
method argument, including assocs, splat, and block argument.
* eval.c (SETUP_ARGS0): prepare block argument as well.
* lib/mathn.rb (Integer): remove Integer#gcd2. [ruby-core:07931]
* eval.c (error_line): print receivers true/false/nil specially.
* eval.c (rb_proc_yield): handles parameters in yield semantics.
* eval.c (nil_yield): gives LocalJumpError to denote no block
error.
* io.c (rb_io_getc): now takes one-character string.
* string.c (rb_str_hash): use FNV-1a hash from Fowler/Noll/Vo
hashing algorithm.
* string.c (rb_str_aref): str[0] now returns 1 character string,
instead of a fixnum. [Ruby2]
* parse.y (parser_yylex): ?c now returns 1 character string,
instead of a fixnum. [Ruby2]
* string.c (rb_str_aset): no longer support fixnum insertion.
* eval.c (umethod_bind): should not update original class.
[ruby-dev:28636]
* eval.c (ev_const_get): should support constant access from
within instance_eval(). [ruby-dev:28327]
* time.c (time_timeval): should round for usec floating
number. [ruby-core:07896]
* time.c (time_add): ditto.
* dir.c (sys_warning): should not call a vararg function
rb_sys_warning() indirectly. [ruby-core:07886]
* numeric.c (flo_divmod): the first element of Float#divmod should
be an integer. [ruby-dev:28589]
* test/ruby/test_float.rb: add tests for divmod, div, modulo and remainder.
* re.c (rb_reg_initialize): should not allow modifying literal
regexps. frozen check moved from rb_reg_initialize_m as well.
* re.c (rb_reg_initialize): should not modify untainted objects in
safe levels higher than 3.
* re.c (rb_memcmp): type change from char* to const void*.
* dir.c (dir_close): should not close untainted dir stream.
* dir.c (GetDIR): add tainted/frozen check for each dir operation.
* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_symbol_arg):
typo fixed. a patch from Florian Gross <florg at florg.net>.
* eval.c (EXEC_EVENT_HOOK): trace_func may remove itself from
event_hooks. no guarantee for arbitrary hook deletion.
[ruby-dev:28632]
* util.c (ruby_strtod): differ addition to minimize error.
[ruby-dev:28619]
* util.c (ruby_strtod): should not raise ERANGE when the input
string does not have any digits. [ruby-dev:28629]
* eval.c (proc_invoke): should restore old ruby_frame->block.
thanks to ts <decoux at moulon.inra.fr>. [ruby-core:07833]
also fix [ruby-dev:28614] as well.
* signal.c (trap): sig should be less then NSIG. Coverity found
this bug. a patch from Kevin Tew <tewk at tewk.com>.
[ruby-core:07823]
* math.c (math_log2): add new method inspired by
[ruby-talk:191237].
* math.c (math_log): add optional base argument to Math::log().
[ruby-talk:191308]
* ext/syck/emitter.c (syck_scan_scalar): avoid accessing
uninitialized array element. a patch from Pat Eyler
<rubypate at gmail.com>. [ruby-core:07809]
* array.c (rb_ary_fill): initialize local variables first. a
patch from Pat Eyler <rubypate at gmail.com>. [ruby-core:07810]
* ext/syck/yaml2byte.c (syck_yaml2byte_handler): need to free
type_tag. a patch from Pat Eyler <rubypate at gmail.com>.
[ruby-core:07808]
* ext/socket/socket.c (make_hostent_internal): accept ai_family
check from Sam Roberts <sroberts at uniserve.com>.
[ruby-core:07691]
* util.c (ruby_strtod): should not cut off 18 digits for no
reason. [ruby-core:07796]
* array.c (rb_ary_fill): internalize local variable "beg" to
pacify Coverity. [ruby-core:07770]
* pack.c (pack_unpack): now supports CRLF newlines. a patch from
<tommy at tmtm.org>. [ruby-dev:28601]
* applied code clean-up patch from Stefan Huehner
<stefan at huehner.org>. [ruby-core:07764]
* lib/jcode.rb (String::tr_s): should have translated non
squeezing character sequence (i.e. a character) as well. thanks
to Hiroshi Ichikawa <gimite at gimite.ddo.jp> [ruby-list:42090]
* ext/socket/socket.c: document update patch from Sam Roberts
<sroberts at uniserve.com>. [ruby-core:07701]
* lib/mathn.rb (Integer): need not to remove gcd2. a patch from
NARUSE, Yui <naruse at airemix.com>. [ruby-dev:28570]
* parse.y (arg): too much NEW_LIST()
* eval.c (SETUP_ARGS0): remove unnecessary access to nd_alen.
* eval.c (rb_eval): use ARGSCAT for NODE_OP_ASGN1.
[ruby-dev:28585]
* parse.y (arg): use NODE_ARGSCAT for placeholder.
* lib/getoptlong.rb (GetoptLong::get): RDoc update patch from
mathew <meta at pobox.com>. [ruby-core:07738]
* variable.c (rb_const_set): raise error when no target klass is
supplied. [ruby-dev:28582]
* prec.c (prec_prec_f): documentation patch from
<gerardo.santana at gmail.com>. [ruby-core:07689]
* bignum.c (rb_big_pow): second operand may be too big even if
it's a Fixnum. [ruby-talk:187984]
* README.EXT: update symbol description. [ruby-talk:188104]
* COPYING: explicitly note GPLv2. [ruby-talk:187922]
* parse.y: remove some obsolete syntax rules (unparenthesized
method calls in argument list).
* eval.c (rb_call0): insecure calling should be checked for non
NODE_SCOPE method invocations too.
* eval.c (rb_alias): should preserve the current safe level as
well as method definition.
* process.c (rb_f_sleep): remove RDoc description about SIGALRM
which is not valid on the current implementation. [ruby-dev:28464]
Thu Mar 23 21:40:47 2006 K.Kosako <sndgk393 AT ybb.ne.jp>
* eval.c (method_missing): should support argument splat in
super. a bug in combination of super, splat and
method_missing. [ruby-talk:185438]
* configure.in: Solaris SunPro compiler -rapth patch from
<kuwa at labs.fujitsu.com>. [ruby-dev:28443]
* configure.in: remove enable_rpath=no for Solaris.
[ruby-dev:28440]
* ext/win32ole/win32ole.c (ole_val2olevariantdata): change behavior
of converting OLE Variant object with VT_ARRAY|VT_UI1 and Ruby
String object.
* ruby.1: a clarification patch from David Lutterkort
<dlutter at redhat.com>. [ruby-core:7508]
* lib/rdoc/ri/ri_paths.rb (RI::Paths): adding paths from rubygems
directories. a patch from Eric Hodel <drbrain at segment7.net>.
[ruby-core:07423]
* eval.c (rb_clear_cache_by_class): clearing wrong cache.
* ext/extmk.rb: use :remove_destination to install extension libraries
to avoid SEGV. [ruby-dev:28417]
* eval.c (rb_thread_fd_writable): should not re-schedule output
from KILLED thread (must be error printing).
* array.c (rb_ary_flatten_bang): allow specifying recursion
level. [ruby-talk:182170]
* array.c (rb_ary_flatten): ditto.
* gc.c (add_heap): a heap_slots may overflow. a patch from Stefan
Weil <weil at mail.berlios.de>.
* eval.c (rb_call): use separate cache for fcall/vcall
invocation.
* eval.c (rb_eval): NODE_FCALL, NODE_VCALL can call local
functions.
* eval.c (rb_mod_local): a new method to specify newly added
visibility "local".
* eval.c (search_method): search for local methods which are
visible only from the current class.
* class.c (rb_class_local_methods): a method to list local methods.
* object.c (Init_Object): add BasicObject class as a top level
BlankSlate class.
* ruby.h (SYM2ID): should not cast to signed long.
[ruby-core:07414]
* class.c (rb_include_module): allow module duplication.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10235 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2006-06-10 01:20:17 +04:00
|
|
|
const char *err;
|
2014-11-29 03:37:12 +03:00
|
|
|
VALUE mesg, error, func, errmsg;
|
2003-05-20 12:18:16 +04:00
|
|
|
VALUE klass = rb_obj_class(self);
|
2003-05-20 05:51:32 +04:00
|
|
|
|
2003-05-21 12:48:05 +04:00
|
|
|
if (klass == rb_eSystemCallError) {
|
* compile.c (iseq_build_body), error.c (set_syserr, get_syserr),
(syserr_initialize), gc.c (define_final, rb_gc_copy_finalizer),
(run_final), hash.c (rb_hash_aref, rb_hash_lookup2),
(rb_hash_fetch_m, rb_hash_clear, rb_hash_aset, eql_i),
iseq.c (iseq_load, iseq_data_to_ary), marshal.c (r_symlink),
thread.c (rb_thread_local_aref),
variable.c (generic_ivar_remove, ivar_get, rb_const_get_0),
(rb_cvar_get), vm.c (rb_vm_check_redefinition_opt_method),
vm_insnhelper.c (vm_get_ev_const), vm_method.c (remove_method),
ext/iconv/iconv.c (map_charset): use st_data_t.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29462 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2010-10-12 18:47:23 +04:00
|
|
|
st_data_t data = (st_data_t)klass;
|
2013-03-15 15:19:56 +04:00
|
|
|
rb_scan_args(argc, argv, "12", &mesg, &error, &func);
|
2003-05-21 12:48:05 +04:00
|
|
|
if (argc == 1 && FIXNUM_P(mesg)) {
|
|
|
|
error = mesg; mesg = Qnil;
|
|
|
|
}
|
* compile.c (iseq_build_body), error.c (set_syserr, get_syserr),
(syserr_initialize), gc.c (define_final, rb_gc_copy_finalizer),
(run_final), hash.c (rb_hash_aref, rb_hash_lookup2),
(rb_hash_fetch_m, rb_hash_clear, rb_hash_aset, eql_i),
iseq.c (iseq_load, iseq_data_to_ary), marshal.c (r_symlink),
thread.c (rb_thread_local_aref),
variable.c (generic_ivar_remove, ivar_get, rb_const_get_0),
(rb_cvar_get), vm.c (rb_vm_check_redefinition_opt_method),
vm_insnhelper.c (vm_get_ev_const), vm_method.c (remove_method),
ext/iconv/iconv.c (map_charset): use st_data_t.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29462 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2010-10-12 18:47:23 +04:00
|
|
|
if (!NIL_P(error) && st_lookup(syserr_tbl, NUM2LONG(error), &data)) {
|
|
|
|
klass = (VALUE)data;
|
2003-05-21 12:48:05 +04:00
|
|
|
/* change class */
|
2011-09-29 15:07:45 +04:00
|
|
|
if (!RB_TYPE_P(self, T_OBJECT)) { /* insurance to avoid type crash */
|
2003-05-21 12:48:05 +04:00
|
|
|
rb_raise(rb_eTypeError, "invalid instance type");
|
|
|
|
}
|
* include/ruby/ruby.h: constify RBasic::klass and add
RBASIC_CLASS(obj) macro which returns a class of `obj'.
This change is a part of RGENGC branch [ruby-trunk - Feature #8339].
* object.c: add new function rb_obj_reveal().
This function reveal interal (hidden) object by rb_obj_hide().
Note that do not change class before and after hiding.
Only permitted example is:
klass = RBASIC_CLASS(obj);
rb_obj_hide(obj);
....
rb_obj_reveal(obj, klass);
TODO: API design. rb_obj_reveal() should be replaced with others.
TODO: modify constified variables using cast may be harmful for
compiler's analysis and optimizaton.
Any idea to prohibt inserting RBasic::klass directly?
If rename RBasic::klass and force to use RBASIC_CLASS(obj),
then all codes such as `RBASIC(obj)->klass' will be
compilation error. Is it acceptable? (We have similar
experience at Ruby 1.9,
for example "RARRAY(ary)->ptr" to "RARRAY_PTR(ary)".
* internal.h: add some macros.
* RBASIC_CLEAR_CLASS(obj) clear RBasic::klass to make it internal
object.
* RBASIC_SET_CLASS(obj, cls) set RBasic::klass.
* RBASIC_SET_CLASS_RAW(obj, cls) same as RBASIC_SET_CLASS
without write barrier (planned).
* RCLASS_SET_SUPER(a, b) set super class of a.
* array.c, class.c, compile.c, encoding.c, enum.c, error.c, eval.c,
file.c, gc.c, hash.c, io.c, iseq.c, marshal.c, object.c,
parse.y, proc.c, process.c, random.c, ruby.c, sprintf.c,
string.c, thread.c, transcode.c, vm.c, vm_eval.c, win32/file.c:
Use above macros and functions to access RBasic::klass.
* ext/coverage/coverage.c, ext/readline/readline.c,
ext/socket/ancdata.c, ext/socket/init.c,
* ext/zlib/zlib.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40691 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-05-13 14:49:11 +04:00
|
|
|
RBASIC_SET_CLASS(self, klass);
|
2003-05-21 12:48:05 +04:00
|
|
|
}
|
2003-05-20 05:51:32 +04:00
|
|
|
}
|
2003-05-21 12:48:05 +04:00
|
|
|
else {
|
2013-03-15 15:19:56 +04:00
|
|
|
rb_scan_args(argc, argv, "02", &mesg, &func);
|
2015-02-16 06:58:28 +03:00
|
|
|
error = rb_const_get(klass, id_Errno);
|
2003-05-20 12:18:16 +04:00
|
|
|
}
|
2009-05-24 17:39:35 +04:00
|
|
|
if (!NIL_P(error)) err = strerror(NUM2INT(error));
|
2003-05-21 12:48:05 +04:00
|
|
|
else err = "unknown error";
|
2014-11-29 03:37:12 +03:00
|
|
|
|
|
|
|
errmsg = rb_enc_str_new_cstr(err, rb_locale_encoding());
|
2003-05-21 12:48:05 +04:00
|
|
|
if (!NIL_P(mesg)) {
|
2012-02-25 02:53:42 +04:00
|
|
|
VALUE str = StringValue(mesg);
|
2014-11-29 03:37:12 +03:00
|
|
|
|
|
|
|
if (!NIL_P(func)) rb_str_catf(errmsg, " @ %"PRIsVALUE, func);
|
|
|
|
rb_str_catf(errmsg, " - %"PRIsVALUE, str);
|
2003-05-20 05:51:32 +04:00
|
|
|
}
|
2014-11-29 03:37:12 +03:00
|
|
|
mesg = errmsg;
|
|
|
|
|
2005-05-14 18:59:53 +04:00
|
|
|
rb_call_super(1, &mesg);
|
2015-02-23 01:57:18 +03:00
|
|
|
rb_ivar_set(self, id_errno, error);
|
2003-05-20 05:51:32 +04:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2003-12-29 06:56:22 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2016-09-08 07:57:49 +03:00
|
|
|
* system_call_error.errno -> integer
|
2003-12-29 06:56:22 +03:00
|
|
|
*
|
|
|
|
* Return this SystemCallError's error number.
|
|
|
|
*/
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
syserr_errno(VALUE self)
|
1999-01-20 07:59:39 +03:00
|
|
|
{
|
2015-02-16 06:58:28 +03:00
|
|
|
return rb_attr_get(self, id_errno);
|
1999-01-20 07:59:39 +03:00
|
|
|
}
|
|
|
|
|
2003-12-29 06:56:22 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:31:22 +04:00
|
|
|
* system_call_error === other -> true or false
|
2003-12-29 06:56:22 +03:00
|
|
|
*
|
|
|
|
* Return +true+ if the receiver is a generic +SystemCallError+, or
|
2010-05-13 09:49:55 +04:00
|
|
|
* if the error numbers +self+ and _other_ are the same.
|
2003-12-29 06:56:22 +03:00
|
|
|
*/
|
|
|
|
|
2001-05-02 08:22:21 +04:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
syserr_eqq(VALUE self, VALUE exc)
|
2001-05-02 08:22:21 +04:00
|
|
|
{
|
2003-08-15 07:01:52 +04:00
|
|
|
VALUE num, e;
|
2001-05-02 08:22:21 +04:00
|
|
|
|
2008-05-24 17:39:57 +04:00
|
|
|
if (!rb_obj_is_kind_of(exc, rb_eSystemCallError)) {
|
2015-02-16 06:58:28 +03:00
|
|
|
if (!rb_respond_to(exc, id_errno)) return Qfalse;
|
2008-05-24 17:39:57 +04:00
|
|
|
}
|
|
|
|
else if (self == rb_eSystemCallError) return Qtrue;
|
2001-05-02 08:22:21 +04:00
|
|
|
|
2015-02-16 06:58:28 +03:00
|
|
|
num = rb_attr_get(exc, id_errno);
|
2001-05-02 08:22:21 +04:00
|
|
|
if (NIL_P(num)) {
|
2015-02-16 07:08:52 +03:00
|
|
|
num = rb_funcallv(exc, id_errno, 0, 0);
|
2001-05-02 08:22:21 +04:00
|
|
|
}
|
2015-02-16 06:58:28 +03:00
|
|
|
e = rb_const_get(self, id_Errno);
|
2021-11-09 11:09:29 +03:00
|
|
|
return RBOOL(FIXNUM_P(num) ? num == e : rb_equal(num, e));
|
2001-05-02 08:22:21 +04:00
|
|
|
}
|
|
|
|
|
2010-05-08 08:50:09 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: StandardError
|
|
|
|
*
|
|
|
|
* The most standard error types are subclasses of StandardError. A
|
|
|
|
* rescue clause without an explicit Exception class will rescue all
|
|
|
|
* StandardErrors (and only those).
|
|
|
|
*
|
|
|
|
* def foo
|
|
|
|
* raise "Oups"
|
|
|
|
* end
|
2010-05-18 01:07:33 +04:00
|
|
|
* foo rescue "Hello" #=> "Hello"
|
2010-05-08 08:50:09 +04:00
|
|
|
*
|
|
|
|
* On the other hand:
|
|
|
|
*
|
|
|
|
* require 'does/not/exist' rescue "Hi"
|
|
|
|
*
|
|
|
|
* <em>raises the exception:</em>
|
|
|
|
*
|
|
|
|
* LoadError: no such file to load -- does/not/exist
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: SystemExit
|
|
|
|
*
|
|
|
|
* Raised by +exit+ to initiate the termination of the script.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: SignalException
|
|
|
|
*
|
|
|
|
* Raised when a signal is received.
|
|
|
|
*
|
|
|
|
* begin
|
|
|
|
* Process.kill('HUP',Process.pid)
|
2013-02-25 23:52:11 +04:00
|
|
|
* sleep # wait for receiver to handle signal sent by Process.kill
|
2010-05-08 08:50:09 +04:00
|
|
|
* rescue SignalException => e
|
|
|
|
* puts "received Exception #{e}"
|
|
|
|
* end
|
|
|
|
*
|
|
|
|
* <em>produces:</em>
|
|
|
|
*
|
|
|
|
* received Exception SIGHUP
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: Interrupt
|
|
|
|
*
|
2018-12-21 00:17:11 +03:00
|
|
|
* Raised when the interrupt signal is received, typically because the
|
|
|
|
* user has pressed Control-C (on most posix platforms). As such, it is a
|
2010-05-08 08:50:09 +04:00
|
|
|
* subclass of +SignalException+.
|
|
|
|
*
|
|
|
|
* begin
|
|
|
|
* puts "Press ctrl-C when you get bored"
|
|
|
|
* loop {}
|
|
|
|
* rescue Interrupt => e
|
|
|
|
* puts "Note: You will typically use Signal.trap instead."
|
|
|
|
* end
|
|
|
|
*
|
|
|
|
* <em>produces:</em>
|
|
|
|
*
|
|
|
|
* Press ctrl-C when you get bored
|
|
|
|
*
|
|
|
|
* <em>then waits until it is interrupted with Control-C and then prints:</em>
|
|
|
|
*
|
|
|
|
* Note: You will typically use Signal.trap instead.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: TypeError
|
|
|
|
*
|
|
|
|
* Raised when encountering an object that is not of the expected type.
|
|
|
|
*
|
|
|
|
* [1, 2, 3].first("two")
|
|
|
|
*
|
|
|
|
* <em>raises the exception:</em>
|
|
|
|
*
|
2013-01-30 02:00:58 +04:00
|
|
|
* TypeError: no implicit conversion of String into Integer
|
2010-05-08 08:50:09 +04:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: ArgumentError
|
|
|
|
*
|
|
|
|
* Raised when the arguments are wrong and there isn't a more specific
|
|
|
|
* Exception class.
|
|
|
|
*
|
|
|
|
* Ex: passing the wrong number of arguments
|
|
|
|
*
|
|
|
|
* [1, 2, 3].first(4, 5)
|
|
|
|
*
|
|
|
|
* <em>raises the exception:</em>
|
|
|
|
*
|
2015-10-25 03:39:29 +03:00
|
|
|
* ArgumentError: wrong number of arguments (given 2, expected 1)
|
2010-05-08 08:50:09 +04:00
|
|
|
*
|
|
|
|
* Ex: passing an argument that is not acceptable:
|
|
|
|
*
|
|
|
|
* [1, 2, 3].first(-4)
|
|
|
|
*
|
|
|
|
* <em>raises the exception:</em>
|
|
|
|
*
|
|
|
|
* ArgumentError: negative array size
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: IndexError
|
|
|
|
*
|
|
|
|
* Raised when the given index is invalid.
|
|
|
|
*
|
|
|
|
* a = [:foo, :bar]
|
|
|
|
* a.fetch(0) #=> :foo
|
|
|
|
* a[4] #=> nil
|
|
|
|
* a.fetch(4) #=> IndexError: index 4 outside of array bounds: -2...2
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: KeyError
|
|
|
|
*
|
|
|
|
* Raised when the specified key is not found. It is a subclass of
|
|
|
|
* IndexError.
|
|
|
|
*
|
|
|
|
* h = {"foo" => :bar}
|
2010-05-18 01:07:33 +04:00
|
|
|
* h.fetch("foo") #=> :bar
|
|
|
|
* h.fetch("baz") #=> KeyError: key not found: "baz"
|
2010-05-08 08:50:09 +04:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: RangeError
|
|
|
|
*
|
|
|
|
* Raised when a given numerical value is out of range.
|
|
|
|
*
|
|
|
|
* [1, 2, 3].drop(1 << 100)
|
|
|
|
*
|
|
|
|
* <em>raises the exception:</em>
|
|
|
|
*
|
|
|
|
* RangeError: bignum too big to convert into `long'
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: ScriptError
|
|
|
|
*
|
|
|
|
* ScriptError is the superclass for errors raised when a script
|
|
|
|
* can not be executed because of a +LoadError+,
|
|
|
|
* +NotImplementedError+ or a +SyntaxError+. Note these type of
|
2010-05-24 18:05:33 +04:00
|
|
|
* +ScriptErrors+ are not +StandardError+ and will not be
|
2010-05-08 08:50:09 +04:00
|
|
|
* rescued unless it is specified explicitly (or its ancestor
|
|
|
|
* +Exception+).
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: SyntaxError
|
|
|
|
*
|
|
|
|
* Raised when encountering Ruby code with an invalid syntax.
|
|
|
|
*
|
|
|
|
* eval("1+1=2")
|
|
|
|
*
|
|
|
|
* <em>raises the exception:</em>
|
|
|
|
*
|
|
|
|
* SyntaxError: (eval):1: syntax error, unexpected '=', expecting $end
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: LoadError
|
|
|
|
*
|
|
|
|
* Raised when a file required (a Ruby script, extension library, ...)
|
|
|
|
* fails to load.
|
|
|
|
*
|
|
|
|
* require 'this/file/does/not/exist'
|
|
|
|
*
|
|
|
|
* <em>raises the exception:</em>
|
|
|
|
*
|
|
|
|
* LoadError: no such file to load -- this/file/does/not/exist
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: NotImplementedError
|
|
|
|
*
|
|
|
|
* Raised when a feature is not implemented on the current platform. For
|
|
|
|
* example, methods depending on the +fsync+ or +fork+ system calls may
|
|
|
|
* raise this exception if the underlying operating system or Ruby
|
|
|
|
* runtime does not support them.
|
|
|
|
*
|
|
|
|
* Note that if +fork+ raises a +NotImplementedError+, then
|
|
|
|
* <code>respond_to?(:fork)</code> returns +false+.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: NameError
|
|
|
|
*
|
|
|
|
* Raised when a given name is invalid or undefined.
|
|
|
|
*
|
|
|
|
* puts foo
|
|
|
|
*
|
|
|
|
* <em>raises the exception:</em>
|
|
|
|
*
|
|
|
|
* NameError: undefined local variable or method `foo' for main:Object
|
|
|
|
*
|
|
|
|
* Since constant names must start with a capital:
|
|
|
|
*
|
2016-10-26 09:11:23 +03:00
|
|
|
* Integer.const_set :answer, 42
|
2010-05-08 08:50:09 +04:00
|
|
|
*
|
|
|
|
* <em>raises the exception:</em>
|
|
|
|
*
|
|
|
|
* NameError: wrong constant name answer
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: NoMethodError
|
|
|
|
*
|
|
|
|
* Raised when a method is called on a receiver which doesn't have it
|
|
|
|
* defined and also fails to respond with +method_missing+.
|
|
|
|
*
|
|
|
|
* "hello".to_ary
|
|
|
|
*
|
|
|
|
* <em>raises the exception:</em>
|
|
|
|
*
|
2023-12-21 23:27:18 +03:00
|
|
|
* NoMethodError: undefined method `to_ary' for an instance of String
|
2010-05-08 08:50:09 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-12-12 03:46:34 +03:00
|
|
|
* Document-class: FrozenError
|
2010-05-08 08:50:09 +04:00
|
|
|
*
|
2017-12-12 03:46:34 +03:00
|
|
|
* Raised when there is an attempt to modify a frozen object.
|
2010-05-08 08:50:09 +04:00
|
|
|
*
|
|
|
|
* [1, 2, 3].freeze << 4
|
|
|
|
*
|
|
|
|
* <em>raises the exception:</em>
|
|
|
|
*
|
2017-12-12 03:46:34 +03:00
|
|
|
* FrozenError: can't modify frozen Array
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: RuntimeError
|
2010-05-08 08:50:09 +04:00
|
|
|
*
|
2017-12-12 03:46:34 +03:00
|
|
|
* A generic error class raised when an invalid operation is attempted.
|
2017-10-15 19:05:06 +03:00
|
|
|
* Kernel#raise will raise a RuntimeError if no Exception class is
|
2010-05-08 08:50:09 +04:00
|
|
|
* specified.
|
|
|
|
*
|
|
|
|
* raise "ouch"
|
|
|
|
*
|
|
|
|
* <em>raises the exception:</em>
|
|
|
|
*
|
|
|
|
* RuntimeError: ouch
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: SecurityError
|
|
|
|
*
|
2019-09-25 06:59:12 +03:00
|
|
|
* No longer used by internal code.
|
2010-05-08 08:50:09 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: NoMemoryError
|
|
|
|
*
|
|
|
|
* Raised when memory allocation fails.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: SystemCallError
|
|
|
|
*
|
|
|
|
* SystemCallError is the base class for all low-level
|
|
|
|
* platform-dependent errors.
|
|
|
|
*
|
|
|
|
* The errors available on the current platform are subclasses of
|
|
|
|
* SystemCallError and are defined in the Errno module.
|
|
|
|
*
|
|
|
|
* File.open("does/not/exist")
|
|
|
|
*
|
|
|
|
* <em>raises the exception:</em>
|
|
|
|
*
|
|
|
|
* Errno::ENOENT: No such file or directory - does/not/exist
|
|
|
|
*/
|
|
|
|
|
2011-06-30 04:22:32 +04:00
|
|
|
/*
|
|
|
|
* Document-class: EncodingError
|
|
|
|
*
|
|
|
|
* EncodingError is the base class for encoding errors.
|
|
|
|
*/
|
|
|
|
|
2010-05-08 08:50:09 +04:00
|
|
|
/*
|
|
|
|
* Document-class: Encoding::CompatibilityError
|
|
|
|
*
|
|
|
|
* Raised by Encoding and String methods when the source encoding is
|
|
|
|
* incompatible with the target encoding.
|
|
|
|
*/
|
|
|
|
|
2011-06-30 04:22:32 +04:00
|
|
|
/*
|
|
|
|
* Document-class: fatal
|
|
|
|
*
|
2024-01-12 16:44:56 +03:00
|
|
|
* +fatal+ is an Exception that is raised when Ruby has encountered a fatal
|
2019-08-12 05:42:59 +03:00
|
|
|
* error and must exit.
|
2011-06-30 04:22:32 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: NameError::message
|
|
|
|
* :nodoc:
|
|
|
|
*/
|
|
|
|
|
2003-12-21 10:28:54 +03:00
|
|
|
/*
|
2020-12-15 04:01:01 +03:00
|
|
|
* Document-class: Exception
|
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* \Class +Exception+ and its subclasses are used to indicate that an error
|
|
|
|
* or other problem has occurred,
|
|
|
|
* and may need to be handled.
|
|
|
|
* See {Exceptions}[rdoc-ref:exceptions.md].
|
2011-10-19 06:52:38 +04:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* An +Exception+ object carries certain information:
|
2019-09-10 01:20:54 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* - The type (the exception's class),
|
|
|
|
* commonly StandardError, RuntimeError, or a subclass of one or the other;
|
|
|
|
* see {Built-In Exception Class Hierarchy}[rdoc-ref:Exception@Built-In+Exception+Class+Hierarchy].
|
|
|
|
* - An optional descriptive message;
|
|
|
|
* see methods ::new, #message.
|
|
|
|
* - Optional backtrace information;
|
|
|
|
* see methods #backtrace, #backtrace_locations, #set_backtrace.
|
|
|
|
* - An optional cause;
|
|
|
|
* see method #cause.
|
2019-09-10 01:20:54 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* == Built-In \Exception \Class Hierarchy
|
2019-09-10 01:20:54 +03:00
|
|
|
*
|
2024-06-26 20:31:40 +03:00
|
|
|
* The hierarchy of built-in subclasses of class +Exception+:
|
2011-10-19 06:32:39 +04:00
|
|
|
*
|
|
|
|
* * NoMemoryError
|
|
|
|
* * ScriptError
|
2024-06-26 20:31:40 +03:00
|
|
|
* * {LoadError}[https://docs.ruby-lang.org/en/master/LoadError.html]
|
2011-10-19 06:32:39 +04:00
|
|
|
* * NotImplementedError
|
|
|
|
* * SyntaxError
|
2014-10-06 16:43:51 +04:00
|
|
|
* * SecurityError
|
2011-10-19 06:32:39 +04:00
|
|
|
* * SignalException
|
|
|
|
* * Interrupt
|
2019-09-10 01:20:54 +03:00
|
|
|
* * StandardError
|
2011-10-19 06:32:39 +04:00
|
|
|
* * ArgumentError
|
2014-11-15 10:28:08 +03:00
|
|
|
* * UncaughtThrowError
|
2014-10-06 16:43:51 +04:00
|
|
|
* * EncodingError
|
|
|
|
* * FiberError
|
2011-10-19 06:32:39 +04:00
|
|
|
* * IOError
|
|
|
|
* * EOFError
|
2014-10-06 16:43:51 +04:00
|
|
|
* * IndexError
|
|
|
|
* * KeyError
|
|
|
|
* * StopIteration
|
2019-08-25 00:05:19 +03:00
|
|
|
* * ClosedQueueError
|
2011-10-19 06:32:39 +04:00
|
|
|
* * LocalJumpError
|
|
|
|
* * NameError
|
|
|
|
* * NoMethodError
|
|
|
|
* * RangeError
|
|
|
|
* * FloatDomainError
|
|
|
|
* * RegexpError
|
2019-09-10 01:20:54 +03:00
|
|
|
* * RuntimeError
|
2018-03-13 05:00:42 +03:00
|
|
|
* * FrozenError
|
2011-10-19 06:32:39 +04:00
|
|
|
* * SystemCallError
|
2024-06-26 20:31:40 +03:00
|
|
|
* * Errno (and its subclasses, representing system errors)
|
2011-10-19 06:32:39 +04:00
|
|
|
* * ThreadError
|
|
|
|
* * TypeError
|
|
|
|
* * ZeroDivisionError
|
|
|
|
* * SystemExit
|
2014-10-06 16:43:51 +04:00
|
|
|
* * SystemStackError
|
2024-06-26 20:31:40 +03:00
|
|
|
* * {fatal}[https://docs.ruby-lang.org/en/master/fatal.html]
|
|
|
|
*
|
2003-12-21 10:28:54 +03:00
|
|
|
*/
|
|
|
|
|
2020-09-05 15:18:45 +03:00
|
|
|
static VALUE
|
|
|
|
exception_alloc(VALUE klass)
|
|
|
|
{
|
|
|
|
return rb_class_allocate_instance(klass);
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
exception_dumper(VALUE exc)
|
|
|
|
{
|
|
|
|
// TODO: Currently, the instance variables "bt" and "bt_locations"
|
|
|
|
// refers to the same object (Array of String). But "bt_locations"
|
|
|
|
// should have an Array of Thread::Backtrace::Locations.
|
|
|
|
|
|
|
|
return exc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2023-12-06 01:54:37 +03:00
|
|
|
ivar_copy_i(ID key, VALUE val, st_data_t exc)
|
2020-09-05 15:18:45 +03:00
|
|
|
{
|
2023-12-06 01:54:37 +03:00
|
|
|
rb_ivar_set((VALUE)exc, key, val);
|
2020-09-05 15:18:45 +03:00
|
|
|
return ST_CONTINUE;
|
|
|
|
}
|
|
|
|
|
2022-12-19 08:10:58 +03:00
|
|
|
void rb_exc_check_circular_cause(VALUE exc);
|
|
|
|
|
2020-09-05 15:18:45 +03:00
|
|
|
static VALUE
|
|
|
|
exception_loader(VALUE exc, VALUE obj)
|
|
|
|
{
|
|
|
|
// The loader function of rb_marshal_define_compat seems to be called for two events:
|
|
|
|
// one is for fixup (r_fixup_compat), the other is for TYPE_USERDEF.
|
|
|
|
// In the former case, the first argument is an instance of Exception (because
|
|
|
|
// we pass rb_eException to rb_marshal_define_compat). In the latter case, the first
|
|
|
|
// argument is a class object (see TYPE_USERDEF case in r_object0).
|
2020-09-15 08:03:22 +03:00
|
|
|
// We want to copy all instance variables (but "bt_locations") from obj to exc.
|
2020-09-05 15:18:45 +03:00
|
|
|
// But we do not want to do so in the second case, so the following branch is for that.
|
|
|
|
if (RB_TYPE_P(exc, T_CLASS)) return obj; // maybe called from Marshal's TYPE_USERDEF
|
|
|
|
|
|
|
|
rb_ivar_foreach(obj, ivar_copy_i, exc);
|
|
|
|
|
2022-12-19 08:10:58 +03:00
|
|
|
rb_exc_check_circular_cause(exc);
|
|
|
|
|
2020-09-15 08:03:41 +03:00
|
|
|
if (rb_attr_get(exc, id_bt) == rb_attr_get(exc, id_bt_locations)) {
|
2020-09-05 15:18:45 +03:00
|
|
|
rb_ivar_set(exc, id_bt_locations, Qnil);
|
|
|
|
}
|
|
|
|
|
|
|
|
return exc;
|
|
|
|
}
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
void
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
Init_Exception(void)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_eException = rb_define_class("Exception", rb_cObject);
|
2020-09-05 15:18:45 +03:00
|
|
|
rb_define_alloc_func(rb_eException, exception_alloc);
|
|
|
|
rb_marshal_define_compat(rb_eException, rb_eException, exception_dumper, exception_loader);
|
2020-06-18 03:19:43 +03:00
|
|
|
rb_define_singleton_method(rb_eException, "exception", rb_class_new_instance, -1);
|
2018-03-22 11:26:23 +03:00
|
|
|
rb_define_singleton_method(rb_eException, "to_tty?", exc_s_to_tty_p, 0);
|
1999-08-13 09:45:20 +04:00
|
|
|
rb_define_method(rb_eException, "exception", exc_exception, -1);
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_define_method(rb_eException, "initialize", exc_initialize, -1);
|
2004-08-28 18:14:11 +04:00
|
|
|
rb_define_method(rb_eException, "==", exc_equal, 1);
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_define_method(rb_eException, "to_s", exc_to_s, 0);
|
2004-04-05 19:55:09 +04:00
|
|
|
rb_define_method(rb_eException, "message", exc_message, 0);
|
2022-02-01 11:59:31 +03:00
|
|
|
rb_define_method(rb_eException, "detailed_message", exc_detailed_message, -1);
|
2018-03-22 11:26:23 +03:00
|
|
|
rb_define_method(rb_eException, "full_message", exc_full_message, -1);
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_define_method(rb_eException, "inspect", exc_inspect, 0);
|
|
|
|
rb_define_method(rb_eException, "backtrace", exc_backtrace, 0);
|
2013-12-13 08:31:06 +04:00
|
|
|
rb_define_method(rb_eException, "backtrace_locations", exc_backtrace_locations, 0);
|
2012-05-24 10:36:44 +04:00
|
|
|
rb_define_method(rb_eException, "set_backtrace", exc_set_backtrace, 1);
|
2013-11-10 17:16:33 +04:00
|
|
|
rb_define_method(rb_eException, "cause", exc_cause, 0);
|
1999-01-20 07:59:39 +03:00
|
|
|
|
|
|
|
rb_eSystemExit = rb_define_class("SystemExit", rb_eException);
|
2002-11-27 01:32:11 +03:00
|
|
|
rb_define_method(rb_eSystemExit, "initialize", exit_initialize, -1);
|
2001-02-19 10:03:06 +03:00
|
|
|
rb_define_method(rb_eSystemExit, "status", exit_status, 0);
|
2004-07-16 06:17:59 +04:00
|
|
|
rb_define_method(rb_eSystemExit, "success?", exit_success_p, 0);
|
2001-02-19 10:03:06 +03:00
|
|
|
|
1999-08-13 09:45:20 +04:00
|
|
|
rb_eFatal = rb_define_class("fatal", rb_eException);
|
|
|
|
rb_eSignal = rb_define_class("SignalException", rb_eException);
|
2001-02-08 12:19:27 +03:00
|
|
|
rb_eInterrupt = rb_define_class("Interrupt", rb_eSignal);
|
1999-01-20 07:59:39 +03:00
|
|
|
|
|
|
|
rb_eStandardError = rb_define_class("StandardError", rb_eException);
|
2001-05-02 08:22:21 +04:00
|
|
|
rb_eTypeError = rb_define_class("TypeError", rb_eStandardError);
|
|
|
|
rb_eArgError = rb_define_class("ArgumentError", rb_eStandardError);
|
|
|
|
rb_eIndexError = rb_define_class("IndexError", rb_eStandardError);
|
2004-09-22 08:48:52 +04:00
|
|
|
rb_eKeyError = rb_define_class("KeyError", rb_eIndexError);
|
2018-01-26 07:51:14 +03:00
|
|
|
rb_define_method(rb_eKeyError, "initialize", key_err_initialize, -1);
|
2017-09-18 11:05:53 +03:00
|
|
|
rb_define_method(rb_eKeyError, "receiver", key_err_receiver, 0);
|
|
|
|
rb_define_method(rb_eKeyError, "key", key_err_key, 0);
|
2001-05-02 08:22:21 +04:00
|
|
|
rb_eRangeError = rb_define_class("RangeError", rb_eStandardError);
|
2006-02-13 07:53:22 +03:00
|
|
|
|
|
|
|
rb_eScriptError = rb_define_class("ScriptError", rb_eException);
|
|
|
|
rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError);
|
2016-04-20 09:52:30 +03:00
|
|
|
rb_define_method(rb_eSyntaxError, "initialize", syntax_error_initialize, -1);
|
2012-03-07 03:38:33 +04:00
|
|
|
|
2022-12-21 22:22:38 +03:00
|
|
|
/* RDoc will use literal name value while parsing rb_attr,
|
|
|
|
* and will render `idPath` as an attribute name without this trick */
|
|
|
|
ID path = idPath;
|
|
|
|
|
2024-09-26 19:00:34 +03:00
|
|
|
/* the path that failed to parse */
|
2022-12-21 22:22:38 +03:00
|
|
|
rb_attr(rb_eSyntaxError, path, TRUE, FALSE, FALSE);
|
2022-11-20 16:59:52 +03:00
|
|
|
|
2006-02-13 07:53:22 +03:00
|
|
|
rb_eLoadError = rb_define_class("LoadError", rb_eScriptError);
|
2024-09-26 19:00:34 +03:00
|
|
|
/* the path that failed to load */
|
2022-12-21 22:22:38 +03:00
|
|
|
rb_attr(rb_eLoadError, path, TRUE, FALSE, FALSE);
|
2012-03-07 03:38:33 +04:00
|
|
|
|
2006-02-13 07:53:22 +03:00
|
|
|
rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError);
|
|
|
|
|
2007-11-02 09:28:52 +03:00
|
|
|
rb_eNameError = rb_define_class("NameError", rb_eStandardError);
|
2003-05-20 05:51:32 +04:00
|
|
|
rb_define_method(rb_eNameError, "initialize", name_err_initialize, -1);
|
2002-03-19 12:03:11 +03:00
|
|
|
rb_define_method(rb_eNameError, "name", name_err_name, 0);
|
2015-06-18 07:32:50 +03:00
|
|
|
rb_define_method(rb_eNameError, "receiver", name_err_receiver, 0);
|
2015-12-08 08:27:10 +03:00
|
|
|
rb_define_method(rb_eNameError, "local_variables", name_err_local_variables, 0);
|
2020-07-27 10:15:28 +03:00
|
|
|
rb_cNameErrorMesg = rb_define_class_under(rb_eNameError, "message", rb_cObject);
|
2021-02-01 12:01:10 +03:00
|
|
|
rb_define_alloc_func(rb_cNameErrorMesg, name_err_mesg_alloc);
|
|
|
|
rb_define_method(rb_cNameErrorMesg, "initialize_copy", name_err_mesg_init_copy, 1);
|
2004-08-28 18:14:11 +04:00
|
|
|
rb_define_method(rb_cNameErrorMesg, "==", name_err_mesg_equal, 1);
|
2004-01-17 17:58:57 +03:00
|
|
|
rb_define_method(rb_cNameErrorMesg, "to_str", name_err_mesg_to_str, 0);
|
2012-12-24 19:58:15 +04:00
|
|
|
rb_define_method(rb_cNameErrorMesg, "_dump", name_err_mesg_dump, 1);
|
2004-01-17 17:58:57 +03:00
|
|
|
rb_define_singleton_method(rb_cNameErrorMesg, "_load", name_err_mesg_load, 1);
|
2001-06-05 11:50:59 +04:00
|
|
|
rb_eNoMethodError = rb_define_class("NoMethodError", rb_eNameError);
|
2003-05-20 05:51:32 +04:00
|
|
|
rb_define_method(rb_eNoMethodError, "initialize", nometh_err_initialize, -1);
|
2002-03-19 12:03:11 +03:00
|
|
|
rb_define_method(rb_eNoMethodError, "args", nometh_err_args, 0);
|
2016-02-28 07:41:38 +03:00
|
|
|
rb_define_method(rb_eNoMethodError, "private_call?", nometh_err_private_call_p, 0);
|
2000-02-01 06:12:21 +03:00
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError);
|
2017-12-12 03:46:34 +03:00
|
|
|
rb_eFrozenError = rb_define_class("FrozenError", rb_eRuntimeError);
|
2019-04-06 10:02:11 +03:00
|
|
|
rb_define_method(rb_eFrozenError, "initialize", frozen_err_initialize, -1);
|
2019-12-14 18:21:19 +03:00
|
|
|
rb_define_method(rb_eFrozenError, "receiver", frozen_err_receiver, 0);
|
2007-11-02 09:28:52 +03:00
|
|
|
rb_eSecurityError = rb_define_class("SecurityError", rb_eException);
|
1999-12-14 09:50:43 +03:00
|
|
|
rb_eNoMemError = rb_define_class("NoMemoryError", rb_eException);
|
2008-09-26 07:53:11 +04:00
|
|
|
rb_eEncodingError = rb_define_class("EncodingError", rb_eStandardError);
|
|
|
|
rb_eEncCompatError = rb_define_class_under(rb_cEncoding, "CompatibilityError", rb_eEncodingError);
|
2020-12-22 20:31:02 +03:00
|
|
|
rb_eNoMatchingPatternError = rb_define_class("NoMatchingPatternError", rb_eStandardError);
|
2021-08-15 03:38:24 +03:00
|
|
|
rb_eNoMatchingPatternKeyError = rb_define_class("NoMatchingPatternKeyError", rb_eNoMatchingPatternError);
|
|
|
|
rb_define_method(rb_eNoMatchingPatternKeyError, "initialize", no_matching_pattern_key_err_initialize, -1);
|
|
|
|
rb_define_method(rb_eNoMatchingPatternKeyError, "matchee", no_matching_pattern_key_err_matchee, 0);
|
|
|
|
rb_define_method(rb_eNoMatchingPatternKeyError, "key", no_matching_pattern_key_err_key, 0);
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2003-08-15 07:01:52 +04:00
|
|
|
syserr_tbl = st_init_numtable();
|
|
|
|
rb_eSystemCallError = rb_define_class("SystemCallError", rb_eStandardError);
|
|
|
|
rb_define_method(rb_eSystemCallError, "initialize", syserr_initialize, -1);
|
|
|
|
rb_define_method(rb_eSystemCallError, "errno", syserr_errno, 0);
|
|
|
|
rb_define_singleton_method(rb_eSystemCallError, "===", syserr_eqq, 1);
|
|
|
|
|
|
|
|
rb_mErrno = rb_define_module("Errno");
|
2003-06-02 08:49:46 +04:00
|
|
|
|
2016-09-27 12:19:14 +03:00
|
|
|
rb_mWarning = rb_define_module("Warning");
|
2019-11-12 12:34:49 +03:00
|
|
|
rb_define_singleton_method(rb_mWarning, "[]", rb_warning_s_aref, 1);
|
|
|
|
rb_define_singleton_method(rb_mWarning, "[]=", rb_warning_s_aset, 2);
|
2024-02-22 16:25:12 +03:00
|
|
|
rb_define_singleton_method(rb_mWarning, "categories", rb_warning_s_categories, 0);
|
2020-08-06 20:25:11 +03:00
|
|
|
rb_define_method(rb_mWarning, "warn", rb_warning_s_warn, -1);
|
2016-09-27 12:19:14 +03:00
|
|
|
rb_extend_object(rb_mWarning, rb_mWarning);
|
|
|
|
|
2018-02-23 05:16:42 +03:00
|
|
|
/* :nodoc: */
|
2017-04-26 23:13:07 +03:00
|
|
|
rb_cWarningBuffer = rb_define_class_under(rb_mWarning, "buffer", rb_cString);
|
2017-10-23 09:42:37 +03:00
|
|
|
rb_define_method(rb_cWarningBuffer, "write", warning_write, -1);
|
2017-04-26 23:13:07 +03:00
|
|
|
|
2015-02-16 06:58:28 +03:00
|
|
|
id_cause = rb_intern_const("cause");
|
|
|
|
id_message = rb_intern_const("message");
|
2022-02-01 11:59:31 +03:00
|
|
|
id_detailed_message = rb_intern_const("detailed_message");
|
2015-02-16 06:58:28 +03:00
|
|
|
id_backtrace = rb_intern_const("backtrace");
|
2017-09-18 11:05:53 +03:00
|
|
|
id_key = rb_intern_const("key");
|
2021-08-15 03:38:24 +03:00
|
|
|
id_matchee = rb_intern_const("matchee");
|
2015-02-16 06:58:28 +03:00
|
|
|
id_args = rb_intern_const("args");
|
2015-10-28 09:36:13 +03:00
|
|
|
id_receiver = rb_intern_const("receiver");
|
2016-02-28 07:41:38 +03:00
|
|
|
id_private_call_p = rb_intern_const("private_call?");
|
2015-12-08 08:27:10 +03:00
|
|
|
id_local_variables = rb_intern_const("local_variables");
|
2015-02-16 06:58:28 +03:00
|
|
|
id_Errno = rb_intern_const("Errno");
|
|
|
|
id_errno = rb_intern_const("errno");
|
|
|
|
id_i_path = rb_intern_const("@path");
|
2016-09-27 12:19:14 +03:00
|
|
|
id_warn = rb_intern_const("warn");
|
2020-09-03 01:49:40 +03:00
|
|
|
id_category = rb_intern_const("category");
|
2020-12-15 09:15:23 +03:00
|
|
|
id_deprecated = rb_intern_const("deprecated");
|
|
|
|
id_experimental = rb_intern_const("experimental");
|
2023-04-13 13:11:14 +03:00
|
|
|
id_performance = rb_intern_const("performance");
|
2024-11-05 21:41:59 +03:00
|
|
|
id_strict_unused_block = rb_intern_const("strict_unused_block");
|
2018-03-22 11:26:23 +03:00
|
|
|
id_top = rb_intern_const("top");
|
|
|
|
id_bottom = rb_intern_const("bottom");
|
2015-12-08 08:27:10 +03:00
|
|
|
id_iseq = rb_make_internal_id();
|
2018-04-12 12:34:54 +03:00
|
|
|
id_recv = rb_make_internal_id();
|
Add rb_category_warn{,ing} for warning messages with categories
This adds the following C-API functions that can be used to emit
warnings with categories included:
```c
void rb_category_warn(const char *, const char*, ...)
void rb_category_warning(const char*, const char*, ...)
```
Internally in error.c, there is an rb_warn_category function
that will call Warning.warn with the string and the category
keyword if it doesn't have an arity of 1, and will call
Warning.warn with just the string if it has an arity of 1.
This refactors the rb_warn_deprecated{,_to_remove} functions
to use rb_warn_category.
This makes Kernel#warn accept a category keyword and pass it
to Warning.warn, so that Ruby methods can more easily emit
warnings with categories. rb_warn_category makes sure that
the passed category is a already defined category symbol
before calling Warning.warn.
The only currently defined warning category is :deprecated,
since that is what is already used. More categories can be
added in later commits.
2020-09-03 18:00:10 +03:00
|
|
|
|
|
|
|
sym_category = ID2SYM(id_category);
|
2022-02-07 10:05:45 +03:00
|
|
|
sym_highlight = ID2SYM(rb_intern_const("highlight"));
|
Add rb_category_warn{,ing} for warning messages with categories
This adds the following C-API functions that can be used to emit
warnings with categories included:
```c
void rb_category_warn(const char *, const char*, ...)
void rb_category_warning(const char*, const char*, ...)
```
Internally in error.c, there is an rb_warn_category function
that will call Warning.warn with the string and the category
keyword if it doesn't have an arity of 1, and will call
Warning.warn with just the string if it has an arity of 1.
This refactors the rb_warn_deprecated{,_to_remove} functions
to use rb_warn_category.
This makes Kernel#warn accept a category keyword and pass it
to Warning.warn, so that Ruby methods can more easily emit
warnings with categories. rb_warn_category makes sure that
the passed category is a already defined category symbol
before calling Warning.warn.
The only currently defined warning category is :deprecated,
since that is what is already used. More categories can be
added in later commits.
2020-09-03 18:00:10 +03:00
|
|
|
|
2020-12-24 04:27:59 +03:00
|
|
|
warning_categories.id2enum = rb_init_identtable();
|
|
|
|
st_add_direct(warning_categories.id2enum, id_deprecated, RB_WARN_CATEGORY_DEPRECATED);
|
|
|
|
st_add_direct(warning_categories.id2enum, id_experimental, RB_WARN_CATEGORY_EXPERIMENTAL);
|
2023-04-13 13:11:14 +03:00
|
|
|
st_add_direct(warning_categories.id2enum, id_performance, RB_WARN_CATEGORY_PERFORMANCE);
|
2024-11-05 21:41:59 +03:00
|
|
|
st_add_direct(warning_categories.id2enum, id_strict_unused_block, RB_WARN_CATEGORY_STRICT_UNUSED_BLOCK);
|
2020-12-24 04:27:59 +03:00
|
|
|
|
|
|
|
warning_categories.enum2id = rb_init_identtable();
|
|
|
|
st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_NONE, 0);
|
|
|
|
st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_DEPRECATED, id_deprecated);
|
|
|
|
st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_EXPERIMENTAL, id_experimental);
|
2023-04-13 13:11:14 +03:00
|
|
|
st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_PERFORMANCE, id_performance);
|
2024-11-05 21:41:59 +03:00
|
|
|
st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_STRICT_UNUSED_BLOCK, id_strict_unused_block);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2012-04-10 14:07:07 +04:00
|
|
|
void
|
2014-06-03 00:23:47 +04:00
|
|
|
rb_enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
|
2012-04-10 14:07:07 +04:00
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
VALUE mesg;
|
|
|
|
|
|
|
|
va_start(args, fmt);
|
|
|
|
mesg = rb_enc_vsprintf(enc, fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
rb_exc_raise(rb_exc_new3(exc, mesg));
|
|
|
|
}
|
|
|
|
|
2019-10-10 11:04:59 +03:00
|
|
|
void
|
|
|
|
rb_vraise(VALUE exc, const char *fmt, va_list ap)
|
2019-10-10 05:55:43 +03:00
|
|
|
{
|
2019-10-10 11:04:59 +03:00
|
|
|
rb_exc_raise(rb_exc_new3(exc, rb_vsprintf(fmt, ap)));
|
2019-10-10 05:55:43 +03:00
|
|
|
}
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
void
|
1999-08-13 09:45:20 +04:00
|
|
|
rb_raise(VALUE exc, const char *fmt, ...)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
1999-01-20 07:59:39 +03:00
|
|
|
va_list args;
|
* compile.c (insn_data_to_s_detail), file.c (rb_stat_inspect),
iseq.c (ruby_iseq_disasm_insn, ruby_iseq_disasm),
process.c (pst_message), re.c (match_inspect): use rb_str_catf.
* dir.c (dir_inspect), iseq.c (iseq_inspect, insn_operand_intern): use
rb_sprintf.
* error.c (rb_name_error, rb_raise, rb_loaderror, rb_fatal): use
rb_vsprintf.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18158 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-07-22 12:53:34 +04:00
|
|
|
va_start(args, fmt);
|
2019-10-10 11:04:59 +03:00
|
|
|
rb_vraise(exc, fmt, args);
|
1999-01-20 07:59:39 +03:00
|
|
|
va_end(args);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2012-03-07 11:30:31 +04:00
|
|
|
NORETURN(static void raise_loaderror(VALUE path, VALUE mesg));
|
|
|
|
|
|
|
|
static void
|
|
|
|
raise_loaderror(VALUE path, VALUE mesg)
|
|
|
|
{
|
|
|
|
VALUE err = rb_exc_new3(rb_eLoadError, mesg);
|
2015-02-16 06:58:28 +03:00
|
|
|
rb_ivar_set(err, id_i_path, path);
|
2012-03-07 11:30:31 +04:00
|
|
|
rb_exc_raise(err);
|
|
|
|
}
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
void
|
1999-08-13 09:45:20 +04:00
|
|
|
rb_loaderror(const char *fmt, ...)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
1999-01-20 07:59:39 +03:00
|
|
|
va_list args;
|
* compile.c (insn_data_to_s_detail), file.c (rb_stat_inspect),
iseq.c (ruby_iseq_disasm_insn, ruby_iseq_disasm),
process.c (pst_message), re.c (match_inspect): use rb_str_catf.
* dir.c (dir_inspect), iseq.c (iseq_inspect, insn_operand_intern): use
rb_sprintf.
* error.c (rb_name_error, rb_raise, rb_loaderror, rb_fatal): use
rb_vsprintf.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18158 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-07-22 12:53:34 +04:00
|
|
|
VALUE mesg;
|
2012-03-07 03:38:33 +04:00
|
|
|
|
|
|
|
va_start(args, fmt);
|
|
|
|
mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args);
|
|
|
|
va_end(args);
|
2012-03-07 11:30:31 +04:00
|
|
|
raise_loaderror(Qnil, mesg);
|
2012-03-07 03:38:33 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
rb_loaderror_with_path(VALUE path, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
VALUE mesg;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
va_start(args, fmt);
|
2010-05-16 08:55:29 +04:00
|
|
|
mesg = rb_enc_vsprintf(rb_locale_encoding(), fmt, args);
|
1999-01-20 07:59:39 +03:00
|
|
|
va_end(args);
|
2012-03-07 11:30:31 +04:00
|
|
|
raise_loaderror(path, mesg);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_notimplement(void)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2007-04-04 19:42:16 +04:00
|
|
|
rb_raise(rb_eNotImpError,
|
2014-11-25 21:44:22 +03:00
|
|
|
"%"PRIsVALUE"() function is unimplemented on this machine",
|
|
|
|
rb_id2str(rb_frame_this_func()));
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
1999-08-13 09:45:20 +04:00
|
|
|
rb_fatal(const char *fmt, ...)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
|
|
|
va_list args;
|
* compile.c (insn_data_to_s_detail), file.c (rb_stat_inspect),
iseq.c (ruby_iseq_disasm_insn, ruby_iseq_disasm),
process.c (pst_message), re.c (match_inspect): use rb_str_catf.
* dir.c (dir_inspect), iseq.c (iseq_inspect, insn_operand_intern): use
rb_sprintf.
* error.c (rb_name_error, rb_raise, rb_loaderror, rb_fatal): use
rb_vsprintf.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18158 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-07-22 12:53:34 +04:00
|
|
|
VALUE mesg;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2019-10-10 11:49:31 +03:00
|
|
|
if (! ruby_thread_has_gvl_p()) {
|
|
|
|
/* The thread has no GVL. Object allocation impossible (cant run GC),
|
|
|
|
* thus no message can be printed out. */
|
|
|
|
fprintf(stderr, "[FATAL] rb_fatal() outside of GVL\n");
|
2023-07-31 21:04:42 +03:00
|
|
|
rb_print_backtrace(stderr);
|
2019-10-10 11:49:31 +03:00
|
|
|
die();
|
|
|
|
}
|
|
|
|
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
va_start(args, fmt);
|
* compile.c (insn_data_to_s_detail), file.c (rb_stat_inspect),
iseq.c (ruby_iseq_disasm_insn, ruby_iseq_disasm),
process.c (pst_message), re.c (match_inspect): use rb_str_catf.
* dir.c (dir_inspect), iseq.c (iseq_inspect, insn_operand_intern): use
rb_sprintf.
* error.c (rb_name_error, rb_raise, rb_loaderror, rb_fatal): use
rb_vsprintf.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18158 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-07-22 12:53:34 +04:00
|
|
|
mesg = rb_vsprintf(fmt, args);
|
1998-01-16 15:13:05 +03:00
|
|
|
va_end(args);
|
|
|
|
|
* compile.c (insn_data_to_s_detail), file.c (rb_stat_inspect),
iseq.c (ruby_iseq_disasm_insn, ruby_iseq_disasm),
process.c (pst_message), re.c (match_inspect): use rb_str_catf.
* dir.c (dir_inspect), iseq.c (iseq_inspect, insn_operand_intern): use
rb_sprintf.
* error.c (rb_name_error, rb_raise, rb_loaderror, rb_fatal): use
rb_vsprintf.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18158 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-07-22 12:53:34 +04:00
|
|
|
rb_exc_fatal(rb_exc_new3(rb_eFatal, mesg));
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2009-03-19 14:40:38 +03:00
|
|
|
static VALUE
|
|
|
|
make_errno_exc(const char *mesg)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
|
|
|
int n = errno;
|
|
|
|
|
2003-05-20 05:51:32 +04:00
|
|
|
errno = 0;
|
|
|
|
if (n == 0) {
|
2003-08-27 17:33:27 +04:00
|
|
|
rb_bug("rb_sys_fail(%s) - errno == 0", mesg ? mesg : "");
|
2001-12-10 10:18:16 +03:00
|
|
|
}
|
2010-11-09 01:30:20 +03:00
|
|
|
return rb_syserr_new(n, mesg);
|
|
|
|
}
|
2001-12-10 10:18:16 +03:00
|
|
|
|
2012-02-24 11:39:59 +04:00
|
|
|
static VALUE
|
|
|
|
make_errno_exc_str(VALUE mesg)
|
|
|
|
{
|
|
|
|
int n = errno;
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
if (!mesg) mesg = Qnil;
|
|
|
|
if (n == 0) {
|
|
|
|
const char *s = !NIL_P(mesg) ? RSTRING_PTR(mesg) : "";
|
|
|
|
rb_bug("rb_sys_fail_str(%s) - errno == 0", s);
|
|
|
|
}
|
|
|
|
return rb_syserr_new_str(n, mesg);
|
|
|
|
}
|
|
|
|
|
2010-11-09 01:30:20 +03:00
|
|
|
VALUE
|
|
|
|
rb_syserr_new(int n, const char *mesg)
|
|
|
|
{
|
|
|
|
VALUE arg;
|
2003-05-21 22:04:11 +04:00
|
|
|
arg = mesg ? rb_str_new2(mesg) : Qnil;
|
2012-02-24 11:39:59 +04:00
|
|
|
return rb_syserr_new_str(n, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
|
|
|
rb_syserr_new_str(int n, VALUE arg)
|
|
|
|
{
|
2009-03-19 14:40:38 +03:00
|
|
|
return rb_class_new_instance(1, &arg, get_syserr(n));
|
|
|
|
}
|
|
|
|
|
2010-11-09 01:30:20 +03:00
|
|
|
void
|
|
|
|
rb_syserr_fail(int e, const char *mesg)
|
|
|
|
{
|
|
|
|
rb_exc_raise(rb_syserr_new(e, mesg));
|
|
|
|
}
|
|
|
|
|
2012-02-24 11:39:59 +04:00
|
|
|
void
|
|
|
|
rb_syserr_fail_str(int e, VALUE mesg)
|
|
|
|
{
|
|
|
|
rb_exc_raise(rb_syserr_new_str(e, mesg));
|
|
|
|
}
|
|
|
|
|
2023-05-12 04:48:35 +03:00
|
|
|
#undef rb_sys_fail
|
2009-03-19 14:40:38 +03:00
|
|
|
void
|
|
|
|
rb_sys_fail(const char *mesg)
|
|
|
|
{
|
|
|
|
rb_exc_raise(make_errno_exc(mesg));
|
|
|
|
}
|
|
|
|
|
2023-05-12 04:48:35 +03:00
|
|
|
#undef rb_sys_fail_str
|
2012-02-24 11:39:59 +04:00
|
|
|
void
|
|
|
|
rb_sys_fail_str(VALUE mesg)
|
|
|
|
{
|
|
|
|
rb_exc_raise(make_errno_exc_str(mesg));
|
|
|
|
}
|
|
|
|
|
2013-03-15 15:19:56 +04:00
|
|
|
#ifdef RUBY_FUNCTION_NAME_STRING
|
|
|
|
void
|
|
|
|
rb_sys_fail_path_in(const char *func_name, VALUE path)
|
|
|
|
{
|
|
|
|
int n = errno;
|
|
|
|
|
|
|
|
errno = 0;
|
2013-10-20 10:29:06 +04:00
|
|
|
rb_syserr_fail_path_in(func_name, n, path);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
rb_syserr_fail_path_in(const char *func_name, int n, VALUE path)
|
2020-04-14 18:59:23 +03:00
|
|
|
{
|
|
|
|
rb_exc_raise(rb_syserr_new_path_in(func_name, n, path));
|
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
|
|
|
rb_syserr_new_path_in(const char *func_name, int n, VALUE path)
|
2013-10-20 10:29:06 +04:00
|
|
|
{
|
|
|
|
VALUE args[2];
|
|
|
|
|
2013-03-15 15:19:56 +04:00
|
|
|
if (!path) path = Qnil;
|
|
|
|
if (n == 0) {
|
|
|
|
const char *s = !NIL_P(path) ? RSTRING_PTR(path) : "";
|
|
|
|
if (!func_name) func_name = "(null)";
|
|
|
|
rb_bug("rb_sys_fail_path_in(%s, %s) - errno == 0",
|
|
|
|
func_name, s);
|
|
|
|
}
|
|
|
|
args[0] = path;
|
|
|
|
args[1] = rb_str_new_cstr(func_name);
|
2020-04-14 18:59:23 +03:00
|
|
|
return rb_class_new_instance(2, args, get_syserr(n));
|
2013-03-15 15:19:56 +04:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-10-30 13:24:41 +03:00
|
|
|
NORETURN(static void rb_mod_exc_raise(VALUE exc, VALUE mod));
|
|
|
|
|
|
|
|
static void
|
|
|
|
rb_mod_exc_raise(VALUE exc, VALUE mod)
|
|
|
|
{
|
|
|
|
rb_extend_object(exc, mod);
|
|
|
|
rb_exc_raise(exc);
|
|
|
|
}
|
|
|
|
|
2009-03-19 14:40:38 +03:00
|
|
|
void
|
|
|
|
rb_mod_sys_fail(VALUE mod, const char *mesg)
|
|
|
|
{
|
|
|
|
VALUE exc = make_errno_exc(mesg);
|
2021-10-30 13:24:41 +03:00
|
|
|
rb_mod_exc_raise(exc, mod);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2012-02-24 11:39:59 +04:00
|
|
|
void
|
|
|
|
rb_mod_sys_fail_str(VALUE mod, VALUE mesg)
|
|
|
|
{
|
|
|
|
VALUE exc = make_errno_exc_str(mesg);
|
2021-10-30 13:24:41 +03:00
|
|
|
rb_mod_exc_raise(exc, mod);
|
2012-02-24 11:39:59 +04:00
|
|
|
}
|
|
|
|
|
2010-11-09 01:30:20 +03:00
|
|
|
void
|
|
|
|
rb_mod_syserr_fail(VALUE mod, int e, const char *mesg)
|
|
|
|
{
|
|
|
|
VALUE exc = rb_syserr_new(e, mesg);
|
2021-10-30 13:24:41 +03:00
|
|
|
rb_mod_exc_raise(exc, mod);
|
2010-11-09 01:30:20 +03:00
|
|
|
}
|
|
|
|
|
2012-02-24 11:39:59 +04:00
|
|
|
void
|
|
|
|
rb_mod_syserr_fail_str(VALUE mod, int e, VALUE mesg)
|
|
|
|
{
|
|
|
|
VALUE exc = rb_syserr_new_str(e, mesg);
|
2021-10-30 13:24:41 +03:00
|
|
|
rb_mod_exc_raise(exc, mod);
|
2012-02-24 11:39:59 +04:00
|
|
|
}
|
|
|
|
|
2017-03-27 13:44:32 +03:00
|
|
|
static void
|
|
|
|
syserr_warning(VALUE mesg, int err)
|
2001-02-19 12:15:27 +03:00
|
|
|
{
|
2015-02-06 11:37:19 +03:00
|
|
|
rb_str_set_len(mesg, RSTRING_LEN(mesg)-1);
|
2017-03-27 13:44:32 +03:00
|
|
|
rb_str_catf(mesg, ": %s\n", strerror(err));
|
2016-09-27 12:19:14 +03:00
|
|
|
rb_write_warning_str(mesg);
|
2001-02-19 12:15:27 +03:00
|
|
|
}
|
|
|
|
|
2017-03-27 16:15:48 +03:00
|
|
|
#if 0
|
|
|
|
void
|
|
|
|
rb_sys_warn(const char *fmt, ...)
|
|
|
|
{
|
|
|
|
if (!NIL_P(ruby_verbose)) {
|
|
|
|
int errno_save = errno;
|
|
|
|
with_warning_string(mesg, 0, fmt) {
|
|
|
|
syserr_warning(mesg, errno_save);
|
|
|
|
}
|
|
|
|
errno = errno_save;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
rb_syserr_warn(int err, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
if (!NIL_P(ruby_verbose)) {
|
|
|
|
with_warning_string(mesg, 0, fmt) {
|
|
|
|
syserr_warning(mesg, err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
rb_sys_enc_warn(rb_encoding *enc, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
if (!NIL_P(ruby_verbose)) {
|
|
|
|
int errno_save = errno;
|
|
|
|
with_warning_string(mesg, enc, fmt) {
|
|
|
|
syserr_warning(mesg, errno_save);
|
|
|
|
}
|
|
|
|
errno = errno_save;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
rb_syserr_enc_warn(int err, rb_encoding *enc, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
if (!NIL_P(ruby_verbose)) {
|
|
|
|
with_warning_string(mesg, enc, fmt) {
|
|
|
|
syserr_warning(mesg, err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-02-06 11:37:24 +03:00
|
|
|
void
|
2017-03-27 13:44:32 +03:00
|
|
|
rb_sys_warning(const char *fmt, ...)
|
2015-02-06 11:37:24 +03:00
|
|
|
{
|
2017-03-27 13:44:32 +03:00
|
|
|
if (RTEST(ruby_verbose)) {
|
|
|
|
int errno_save = errno;
|
|
|
|
with_warning_string(mesg, 0, fmt) {
|
|
|
|
syserr_warning(mesg, errno_save);
|
|
|
|
}
|
|
|
|
errno = errno_save;
|
|
|
|
}
|
|
|
|
}
|
2015-02-06 11:37:24 +03:00
|
|
|
|
2017-03-27 16:15:48 +03:00
|
|
|
#if 0
|
|
|
|
void
|
|
|
|
rb_syserr_warning(int err, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
if (RTEST(ruby_verbose)) {
|
|
|
|
with_warning_string(mesg, 0, fmt) {
|
|
|
|
syserr_warning(mesg, err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-03-27 13:44:32 +03:00
|
|
|
void
|
|
|
|
rb_sys_enc_warning(rb_encoding *enc, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
if (RTEST(ruby_verbose)) {
|
|
|
|
int errno_save = errno;
|
|
|
|
with_warning_string(mesg, enc, fmt) {
|
|
|
|
syserr_warning(mesg, errno_save);
|
|
|
|
}
|
|
|
|
errno = errno_save;
|
|
|
|
}
|
2015-02-06 11:37:24 +03:00
|
|
|
}
|
|
|
|
|
2017-03-27 16:15:48 +03:00
|
|
|
void
|
|
|
|
rb_syserr_enc_warning(int err, rb_encoding *enc, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
if (RTEST(ruby_verbose)) {
|
|
|
|
with_warning_string(mesg, enc, fmt) {
|
|
|
|
syserr_warning(mesg, err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-01-09 10:26:21 +03:00
|
|
|
void
|
2012-03-07 11:30:31 +04:00
|
|
|
rb_load_fail(VALUE path, const char *err)
|
2001-01-09 10:26:21 +03:00
|
|
|
{
|
2012-03-07 11:30:31 +04:00
|
|
|
VALUE mesg = rb_str_buf_new_cstr(err);
|
|
|
|
rb_str_cat2(mesg, " -- ");
|
|
|
|
rb_str_append(mesg, path); /* should be ASCII compatible */
|
|
|
|
raise_loaderror(path, mesg);
|
2001-01-09 10:26:21 +03:00
|
|
|
}
|
|
|
|
|
2000-02-01 06:12:21 +03:00
|
|
|
void
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_error_frozen(const char *what)
|
2000-02-01 06:12:21 +03:00
|
|
|
{
|
2017-12-12 03:46:34 +03:00
|
|
|
rb_raise(rb_eFrozenError, "can't modify frozen %s", what);
|
2000-02-01 06:12:21 +03:00
|
|
|
}
|
|
|
|
|
2019-04-06 10:02:11 +03:00
|
|
|
void
|
|
|
|
rb_frozen_error_raise(VALUE frozen_obj, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
VALUE exc, mesg;
|
|
|
|
|
|
|
|
va_start(args, fmt);
|
|
|
|
mesg = rb_vsprintf(fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
exc = rb_exc_new3(rb_eFrozenError, mesg);
|
|
|
|
rb_ivar_set(exc, id_recv, frozen_obj);
|
|
|
|
rb_exc_raise(exc);
|
|
|
|
}
|
|
|
|
|
2019-06-05 07:02:38 +03:00
|
|
|
static VALUE
|
|
|
|
inspect_frozen_obj(VALUE obj, VALUE mesg, int recur)
|
|
|
|
{
|
|
|
|
if (recur) {
|
|
|
|
rb_str_cat_cstr(mesg, " ...");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rb_str_append(mesg, rb_inspect(obj));
|
|
|
|
}
|
|
|
|
return mesg;
|
|
|
|
}
|
|
|
|
|
2024-10-14 12:28:59 +03:00
|
|
|
static VALUE
|
|
|
|
get_created_info(VALUE obj, int *pline)
|
|
|
|
{
|
|
|
|
VALUE info = rb_attr_get(obj, id_debug_created_info);
|
|
|
|
|
|
|
|
if (NIL_P(info)) return Qnil;
|
|
|
|
|
|
|
|
VALUE path = rb_ary_entry(info, 0);
|
|
|
|
VALUE line = rb_ary_entry(info, 1);
|
|
|
|
if (NIL_P(path)) return Qnil;
|
|
|
|
*pline = NUM2INT(line);
|
|
|
|
return StringValue(path);
|
|
|
|
}
|
|
|
|
|
2014-09-19 05:46:42 +04:00
|
|
|
void
|
|
|
|
rb_error_frozen_object(VALUE frozen_obj)
|
|
|
|
{
|
2024-02-23 22:08:09 +03:00
|
|
|
rb_yjit_lazy_push_frame(GET_EC()->cfp->pc);
|
2023-12-01 13:33:00 +03:00
|
|
|
|
2019-06-05 07:02:38 +03:00
|
|
|
VALUE mesg = rb_sprintf("can't modify frozen %"PRIsVALUE": ",
|
|
|
|
CLASS_OF(frozen_obj));
|
|
|
|
VALUE exc = rb_exc_new_str(rb_eFrozenError, mesg);
|
|
|
|
|
|
|
|
rb_ivar_set(exc, id_recv, frozen_obj);
|
|
|
|
rb_exec_recursive(inspect_frozen_obj, frozen_obj, mesg);
|
2015-11-21 02:49:31 +03:00
|
|
|
|
2024-10-14 12:28:59 +03:00
|
|
|
int created_line;
|
|
|
|
VALUE created_path = get_created_info(frozen_obj, &created_line);
|
|
|
|
if (!NIL_P(created_path)) {
|
|
|
|
rb_str_catf(mesg, ", created at %"PRIsVALUE":%d", created_path, created_line);
|
2015-10-23 22:02:55 +03:00
|
|
|
}
|
2019-06-05 07:02:38 +03:00
|
|
|
rb_exc_raise(exc);
|
2014-09-19 05:46:42 +04:00
|
|
|
}
|
|
|
|
|
2024-10-14 12:28:59 +03:00
|
|
|
void
|
2024-11-13 17:20:00 +03:00
|
|
|
rb_warn_unchilled_literal(VALUE obj)
|
2024-10-14 12:28:59 +03:00
|
|
|
{
|
|
|
|
rb_warning_category_t category = RB_WARN_CATEGORY_DEPRECATED;
|
|
|
|
if (!NIL_P(ruby_verbose) && rb_warning_category_enabled_p(category)) {
|
|
|
|
int line;
|
|
|
|
VALUE file = rb_source_location(&line);
|
|
|
|
VALUE mesg = NIL_P(file) ? rb_str_new(0, 0) : rb_str_dup(file);
|
|
|
|
|
|
|
|
if (!NIL_P(file)) {
|
|
|
|
if (line) rb_str_catf(mesg, ":%d", line);
|
|
|
|
rb_str_cat2(mesg, ": ");
|
|
|
|
}
|
|
|
|
rb_str_cat2(mesg, "warning: literal string will be frozen in the future");
|
|
|
|
|
|
|
|
VALUE str = obj;
|
|
|
|
if (STR_SHARED_P(str)) {
|
|
|
|
str = RSTRING(obj)->as.heap.aux.shared;
|
|
|
|
}
|
|
|
|
VALUE created = get_created_info(str, &line);
|
|
|
|
if (NIL_P(created)) {
|
|
|
|
rb_str_cat2(mesg, " (run with --debug-frozen-string-literal for more information)\n");
|
|
|
|
} else {
|
|
|
|
rb_str_cat2(mesg, "\n");
|
|
|
|
rb_str_append(mesg, created);
|
|
|
|
if (line) rb_str_catf(mesg, ":%d", line);
|
|
|
|
rb_str_cat2(mesg, ": info: the string was created here\n");
|
|
|
|
}
|
|
|
|
rb_warn_category(mesg, rb_warning_category_to_name(category));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-13 17:20:00 +03:00
|
|
|
void
|
|
|
|
rb_warn_unchilled_symbol_to_s(VALUE obj)
|
|
|
|
{
|
|
|
|
rb_category_warn(
|
|
|
|
RB_WARN_CATEGORY_DEPRECATED,
|
|
|
|
"warning: string returned by :%s.to_s will be frozen in the future", RSTRING_PTR(obj)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2010-10-24 12:05:55 +04:00
|
|
|
#undef rb_check_frozen
|
2002-09-03 09:20:14 +04:00
|
|
|
void
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_check_frozen(VALUE obj)
|
2002-09-03 09:20:14 +04:00
|
|
|
{
|
2024-07-19 22:53:16 +03:00
|
|
|
rb_check_frozen_inline(obj);
|
2002-09-03 09:20:14 +04:00
|
|
|
}
|
|
|
|
|
2012-06-22 08:32:39 +04:00
|
|
|
void
|
|
|
|
rb_check_copyable(VALUE obj, VALUE orig)
|
|
|
|
{
|
|
|
|
if (!FL_ABLE(obj)) return;
|
2024-05-30 15:55:32 +03:00
|
|
|
rb_check_frozen(obj);
|
2012-06-22 08:32:39 +04:00
|
|
|
if (!FL_ABLE(orig)) return;
|
|
|
|
}
|
|
|
|
|
2009-11-24 03:26:52 +03:00
|
|
|
void
|
|
|
|
Init_syserr(void)
|
2008-11-18 20:39:33 +03:00
|
|
|
{
|
2024-01-11 16:46:49 +03:00
|
|
|
rb_eNOERROR = setup_syserr(0, "NOERROR");
|
|
|
|
#if 0
|
|
|
|
/* No error */
|
|
|
|
rb_define_const(rb_mErrno, "NOERROR", rb_eNOERROR);
|
|
|
|
#endif
|
2010-12-12 05:54:23 +03:00
|
|
|
#define defined_error(name, num) set_syserr((num), (name));
|
2024-01-13 10:34:32 +03:00
|
|
|
#define undefined_error(name) rb_define_const(rb_mErrno, (name), rb_eNOERROR);
|
2009-11-24 03:26:52 +03:00
|
|
|
#include "known_errors.inc"
|
|
|
|
#undef defined_error
|
|
|
|
#undef undefined_error
|
|
|
|
}
|
2017-07-22 15:26:19 +03:00
|
|
|
|
2019-12-10 14:22:42 +03:00
|
|
|
#include "warning.rbinc"
|
|
|
|
|
2017-07-22 15:26:19 +03:00
|
|
|
/*!
|
|
|
|
* \}
|
|
|
|
*/
|