Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion doc/string/encode.rdoc
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
Returns a copy of +self+ transcoded as determined by +dst_encoding+.
Returns a copy of +self+ transcoded as determined by +dst_encoding+;
see {Encodings}[rdoc-ref:encodings.rdoc].

By default, raises an exception if +self+
contains an invalid byte or a character not defined in +dst_encoding+;
that behavior may be modified by encoding options; see below.
Expand Down Expand Up @@ -45,3 +47,4 @@ given, conversion from an encoding +enc+ to the same encoding +enc+
no-op, i.e. the string is simply copied without any changes, and no
exceptions are raised, even if there are invalid bytes.

Related: see {Converting to New String}[rdoc-ref:String@Converting+to+New+String].
17 changes: 8 additions & 9 deletions doc/string/end_with_p.rdoc
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
Returns whether +self+ ends with any of the given +strings+.
Returns whether +self+ ends with any of the given +strings+:

Returns +true+ if any given string matches the end, +false+ otherwise:
'foo'.end_with?('oo') # => true
'foo'.end_with?('bar', 'oo') # => true
'foo'.end_with?('bar', 'baz') # => false
'foo'.end_with?('') # => true
'тест'.end_with?('т') # => true
'こんにちは'.end_with?('は') # => true

'hello'.end_with?('ello') #=> true
'hello'.end_with?('heaven', 'ello') #=> true
'hello'.end_with?('heaven', 'paradise') #=> false
'тест'.end_with?('т') # => true
'こんにちは'.end_with?('は') # => true

Related: String#start_with?.
Related: see {Querying}[rdoc-ref:String@Querying].
18 changes: 18 additions & 0 deletions doc/string/eql_p.rdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Returns whether +self+ and +object+ have the same length and content:

s = 'foo'
s.eql?('foo') # => true
s.eql?('food') # => false
s.eql?('FOO') # => false

Returns +false+ if the two strings' encodings are not compatible:

s0 = "äöü" # => "äöü"
s1 = s0.encode(Encoding::ISO_8859_1) # => "\xE4\xF6\xFC"
s0.encoding # => #<Encoding:UTF-8>
s1.encoding # => #<Encoding:ISO-8859-1>
s0.eql?(s1) # => false

See {Encodings}[rdoc-ref:encodings.rdoc].

Related: see {Querying}[rdoc-ref:String@Querying].
15 changes: 8 additions & 7 deletions doc/string/force_encoding.rdoc
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
Changes the encoding of +self+ to +encoding+,
Changes the encoding of +self+ to the given +encoding+,
which may be a string encoding name or an Encoding object;
does not change the underlying bytes;
returns self:

s = 'łał'
s.bytes # => [197, 130, 97, 197, 130]
s.encoding # => #<Encoding:UTF-8>
s.force_encoding('ascii') # => "\xC5\x82a\xC5\x82"
s.encoding # => #<Encoding:US-ASCII>

Does not change the underlying bytes:

s.valid_encoding? # => true
s.bytes # => [197, 130, 97, 197, 130]

Makes the change even if the given +encoding+ is invalid
for +self+ (as is the change above):

s.valid_encoding? # => false
s.force_encoding(Encoding::UTF_8) # => "łał"
s.valid_encoding? # => true
s.valid_encoding? # => false

See {Encodings}[rdoc-ref:encodings.rdoc].

Related: see {Modifying}[rdoc-ref:String@Modifying].
26 changes: 26 additions & 0 deletions doc/string/getbyte.rdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Returns the byte at zero-based +index+ as an integer:

s = 'foo'
s.getbyte(0) # => 102
s.getbyte(1) # => 111
s.getbyte(2) # => 111

Counts backward from the end if +index+ is negative:

s.getbyte(-3) # => 102

Returns +nil+ if +index+ is out of range:

s.getbyte(3) # => nil
s.getbyte(-4) # => nil

More examples:

s = 'тест'
s.bytes # => [209, 130, 208, 181, 209, 129, 209, 130]
s.getbyte(2) # => 208
s = 'こんにちは'
s.bytes # => [227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175]
s.getbyte(2) # => 147

Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString].
15 changes: 8 additions & 7 deletions ext/openssl/ossl_pkcs7.c
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,6 @@ ossl_pkcs7_verify(int argc, VALUE *argv, VALUE self)
BIO *in, *out;
PKCS7 *p7;
VALUE data;
const char *msg;

GetPKCS7(self, p7);
rb_scan_args(argc, argv, "22", &certs, &store, &indata, &flags);
Expand All @@ -794,14 +793,16 @@ ossl_pkcs7_verify(int argc, VALUE *argv, VALUE self)
ok = PKCS7_verify(p7, x509s, x509st, in, out, flg);
BIO_free(in);
sk_X509_pop_free(x509s, X509_free);
if (ok < 0) ossl_raise(ePKCS7Error, "PKCS7_verify");
msg = ERR_reason_error_string(ERR_peek_error());
ossl_pkcs7_set_err_string(self, msg ? rb_str_new2(msg) : Qnil);
ossl_clear_error();
data = ossl_membio2str(out);
ossl_pkcs7_set_data(self, data);

return (ok == 1) ? Qtrue : Qfalse;
if (ok != 1) {
const char *msg = ERR_reason_error_string(ERR_peek_error());
ossl_pkcs7_set_err_string(self, msg ? rb_str_new_cstr(msg) : Qnil);
ossl_clear_error();
return Qfalse;
}
ossl_pkcs7_set_err_string(self, Qnil);
return Qtrue;
}

static VALUE
Expand Down
25 changes: 7 additions & 18 deletions io.c
Original file line number Diff line number Diff line change
Expand Up @@ -9999,14 +9999,14 @@ io_wait(int argc, VALUE *argv, VALUE io)
}

static void
argf_mark(void *ptr)
argf_mark_and_move(void *ptr)
{
struct argf *p = ptr;
rb_gc_mark(p->filename);
rb_gc_mark(p->current_file);
rb_gc_mark(p->argv);
rb_gc_mark(p->inplace);
rb_gc_mark(p->encs.ecopts);
rb_gc_mark_and_move(&p->filename);
rb_gc_mark_and_move(&p->current_file);
rb_gc_mark_and_move(&p->argv);
rb_gc_mark_and_move(&p->inplace);
rb_gc_mark_and_move(&p->encs.ecopts);
}

static size_t
Expand All @@ -10017,20 +10017,9 @@ argf_memsize(const void *ptr)
return size;
}

static void
argf_compact(void *ptr)
{
struct argf *p = ptr;
p->filename = rb_gc_location(p->filename);
p->current_file = rb_gc_location(p->current_file);
p->argv = rb_gc_location(p->argv);
p->inplace = rb_gc_location(p->inplace);
p->encs.ecopts = rb_gc_location(p->encs.ecopts);
}

static const rb_data_type_t argf_type = {
"ARGF",
{argf_mark, RUBY_TYPED_DEFAULT_FREE, argf_memsize, argf_compact},
{argf_mark_and_move, RUBY_TYPED_DEFAULT_FREE, argf_memsize, argf_mark_and_move},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};

Expand Down
2 changes: 1 addition & 1 deletion lib/mkmf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,7 @@ def try_func(func, libs, headers = nil, opt = "", &b)
v
}
unless strvars.empty?
prepare << "char " << strvars.map {|v| "#{v}[1024]"}.join(", ") << "; "
prepare << "char " << strvars.map {|v| %[#{v}[1024] = ""]}.join(", ") << "; "
end
when nil
call = ""
Expand Down
66 changes: 39 additions & 27 deletions ractor.c
Original file line number Diff line number Diff line change
Expand Up @@ -2284,58 +2284,67 @@ static const rb_data_type_t cross_ractor_require_data_type = {
NULL, // memsize
NULL, // compact
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_DECL_MARKING
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_DECL_MARKING
};

static VALUE
require_body(VALUE data)
require_body(VALUE crr_obj)
{
struct cross_ractor_require *crr = (struct cross_ractor_require *)data;
struct cross_ractor_require *crr;
TypedData_Get_Struct(crr_obj, struct cross_ractor_require, &cross_ractor_require_data_type, crr);

ID require;
CONST_ID(require, "require");

if (crr->silent) {
int rb_require_internal_silent(VALUE fname);
crr->result = INT2NUM(rb_require_internal_silent(crr->feature));

RB_OBJ_WRITE(crr_obj, &crr->result, INT2NUM(rb_require_internal_silent(crr->feature)));
}
else {
crr->result = rb_funcallv(Qnil, require, 1, &crr->feature);
RB_OBJ_WRITE(crr_obj, &crr->result, rb_funcallv(Qnil, require, 1, &crr->feature));
}

return Qnil;
}

static VALUE
require_rescue(VALUE data, VALUE errinfo)
require_rescue(VALUE crr_obj, VALUE errinfo)
{
struct cross_ractor_require *crr = (struct cross_ractor_require *)data;
crr->exception = errinfo;
struct cross_ractor_require *crr;
TypedData_Get_Struct(crr_obj, struct cross_ractor_require, &cross_ractor_require_data_type, crr);

RB_OBJ_WRITE(crr_obj, &crr->exception, errinfo);

return Qundef;
}

static VALUE
require_result_copy_body(VALUE data)
require_result_copy_body(VALUE crr_obj)
{
struct cross_ractor_require *crr = (struct cross_ractor_require *)data;
struct cross_ractor_require *crr;
TypedData_Get_Struct(crr_obj, struct cross_ractor_require, &cross_ractor_require_data_type, crr);

if (crr->exception != Qundef) {
VM_ASSERT(crr->result == Qundef);
crr->exception = ractor_copy(crr->exception);
RB_OBJ_WRITE(crr_obj, &crr->exception, ractor_copy(crr->exception));
}
else{
VM_ASSERT(crr->result != Qundef);
crr->result = ractor_copy(crr->result);
RB_OBJ_WRITE(crr_obj, &crr->result, ractor_copy(crr->result));
}

return Qnil;
}

static VALUE
require_result_copy_resuce(VALUE data, VALUE errinfo)
require_result_copy_resuce(VALUE crr_obj, VALUE errinfo)
{
struct cross_ractor_require *crr = (struct cross_ractor_require *)data;
crr->exception = errinfo; // ractor_move(crr->exception);
struct cross_ractor_require *crr;
TypedData_Get_Struct(crr_obj, struct cross_ractor_require, &cross_ractor_require_data_type, crr);

RB_OBJ_WRITE(crr_obj, &crr->exception, errinfo);

return Qnil;
}

Expand All @@ -2353,16 +2362,16 @@ ractor_require_protect(VALUE crr_obj, VALUE (*func)(VALUE))
}

// catch any error
rb_rescue2(func, (VALUE)crr,
require_rescue, (VALUE)crr, rb_eException, 0);
rb_rescue2(func, crr_obj,
require_rescue, crr_obj, rb_eException, 0);

if (silent) {
ruby_debug = debug;
rb_set_errinfo(errinfo);
}

rb_rescue2(require_result_copy_body, (VALUE)crr,
require_result_copy_resuce, (VALUE)crr, rb_eException, 0);
rb_rescue2(require_result_copy_body, crr_obj,
require_result_copy_resuce, crr_obj, rb_eException, 0);

ractor_port_send(GET_EC(), crr->port, Qtrue, Qfalse);
RB_GC_GUARD(crr_obj);
Expand All @@ -2386,8 +2395,8 @@ rb_ractor_require(VALUE feature, bool silent)
FL_SET_RAW(crr_obj, RUBY_FL_SHAREABLE);

// Convert feature to proper file path and make it shareable as fstring
crr->feature = rb_fstring(FilePathValue(feature));
crr->port = ractor_port_new(GET_RACTOR());
RB_OBJ_WRITE(crr_obj, &crr->feature, rb_fstring(FilePathValue(feature)));
RB_OBJ_WRITE(crr_obj, &crr->port, ractor_port_new(GET_RACTOR()));
crr->result = Qundef;
crr->exception = Qundef;
crr->silent = silent;
Expand Down Expand Up @@ -2422,10 +2431,13 @@ ractor_require(rb_execution_context_t *ec, VALUE self, VALUE feature)
}

static VALUE
autoload_load_body(VALUE data)
autoload_load_body(VALUE crr_obj)
{
struct cross_ractor_require *crr = (struct cross_ractor_require *)data;
crr->result = rb_autoload_load(crr->module, crr->name);
struct cross_ractor_require *crr;
TypedData_Get_Struct(crr_obj, struct cross_ractor_require, &cross_ractor_require_data_type, crr);

RB_OBJ_WRITE(crr_obj, &crr->result, rb_autoload_load(crr->module, crr->name));

return Qnil;
}

Expand All @@ -2441,9 +2453,9 @@ rb_ractor_autoload_load(VALUE module, ID name)
struct cross_ractor_require *crr;
VALUE crr_obj = TypedData_Make_Struct(0, struct cross_ractor_require, &cross_ractor_require_data_type, crr);
FL_SET_RAW(crr_obj, RUBY_FL_SHAREABLE);
crr->module = module;
crr->name = name;
crr->port = ractor_port_new(GET_RACTOR());
RB_OBJ_WRITE(crr_obj, &crr->module, module);
RB_OBJ_WRITE(crr_obj, &crr->name, name);
RB_OBJ_WRITE(crr_obj, &crr->port, ractor_port_new(GET_RACTOR()));
crr->result = Qundef;
crr->exception = Qundef;

Expand Down
20 changes: 2 additions & 18 deletions string.c
Original file line number Diff line number Diff line change
Expand Up @@ -4243,17 +4243,7 @@ rb_str_equal(VALUE str1, VALUE str2)
* call-seq:
* eql?(object) -> true or false
*
* Returns +true+ if +object+ has the same length and content;
* as +self+; +false+ otherwise:
*
* s = 'foo'
* s.eql?('foo') # => true
* s.eql?('food') # => false
* s.eql?('FOO') # => false
*
* Returns +false+ if the two strings' encodings are not compatible:
*
* "\u{e4 f6 fc}".encode(Encoding::ISO_8859_1).eql?("\u{c4 d6 dc}") # => false
* :include: doc/string/eql_p.rdoc
*
*/

Expand Down Expand Up @@ -6695,14 +6685,8 @@ rb_str_chr(VALUE str)
* call-seq:
* getbyte(index) -> integer or nil
*
* Returns the byte at zero-based +index+ as an integer, or +nil+ if +index+ is out of range:
*
* s = 'abcde' # => "abcde"
* s.getbyte(0) # => 97
* s.getbyte(-1) # => 101
* s.getbyte(5) # => nil
* :include: doc/string/getbyte.rdoc
*
* Related: String#setbyte.
*/
VALUE
rb_str_getbyte(VALUE str, VALUE index)
Expand Down
Loading