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
2 changes: 1 addition & 1 deletion .github/actions/setup/directories/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ runs:
echo final='rmdir ${{ inputs.builddir }}' >> $GITHUB_OUTPUT

- name: clean
uses: gacts/run-and-post-run@d803f6920adc9a47eeac4cb6c93dbc2e2890c684 # v1.4.2
uses: gacts/run-and-post-run@81b6ce503cde93862cec047c54652e45c5dca991 # v1.4.3
with:
working-directory:
post: |
Expand Down
29 changes: 29 additions & 0 deletions doc/stringio/getbyte.rdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Reads and returns the next integer byte (not character) from the stream:

s = 'foo'
s.bytes # => [102, 111, 111]
strio = StringIO.new(s)
strio.getbyte # => 102
strio.getbyte # => 111
strio.getbyte # => 111

Returns +nil+ if at end-of-stream:

strio.eof? # => true
strio.getbyte # => nil

Returns a byte, not a character:

s = 'тест'
s.bytes # => [209, 130, 208, 181, 209, 129, 209, 130]
strio = StringIO.new(s)
strio.getbyte # => 209
strio.getbyte # => 130

s = 'こんにちは'
s.bytes # => [227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175]
strio = StringIO.new(s)
strio.getbyte # => 227
strio.getbyte # => 129

Related: StringIO.getc.
98 changes: 98 additions & 0 deletions doc/stringio/gets.rdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
Reads and returns a line from the stream;
returns +nil+ if at end-of-stream.

Side effects:

- Increments stream position by the number of bytes read.
- Assigns the return value to global variable <tt>$_</tt>.

With no arguments given, reads a line using the default record separator
(global variable <tt>$/</tt>,* whose initial value is <tt>"\n"</tt>):

strio = StringIO.new(TEXT)
strio.pos # => 0
strio.gets # => "First line\n"
strio.pos # => 11
$_ # => "First line\n"
strio.gets # => "Second line\n"
strio.read # => "\nFourth line\nFifth line\n"
strio.eof? # => true
strio.gets # => nil

strio = StringIO.new('тест') # Four 2-byte characters.
strio.pos # => 0
strio.gets # => "тест"
strio.pos # => 8

<b>Argument +sep+</b>

With only string argument +sep+ given, reads a line using that string as the record separator:

strio = StringIO.new(TEXT)
strio.gets(' ') # => "First "
strio.gets(' ') # => "line\nSecond "
strio.gets(' ') # => "line\n\nFourth "

<b>Argument +limit+</b>

With only integer argument +limit+ given,
reads a line using the default record separator;
limits the size (in characters) of each line to the given limit:

strio = StringIO.new(TEXT)
strio.gets(10) # => "First line"
strio.gets(10) # => "\n"
strio.gets(10) # => "Second lin"
strio.gets(10) # => "e\n"

<b>Arguments +sep+ and +limit+</b>

With arguments +sep+ and +limit+ both given, honors both:

strio = StringIO.new(TEXT)
strio.gets(' ', 10) # => "First "
strio.gets(' ', 10) # => "line\nSecon"
strio.gets(' ', 10) # => "d "

<b>Position</b>

As stated above, method +gets+ reads and returns the next line in the stream.

In the examples above each +strio+ object starts with its position at beginning-of-stream;
but in other cases the position may be anywhere:

strio = StringIO.new(TEXT)
strio.pos = 12
strio.gets # => "econd line\n"

The position need not be at a character boundary:

strio = StringIO.new('тест') # Four 2-byte characters.
strio.pos = 2 # At beginning of second character.
strio.gets # => "ест"
strio.pos = 3 # In middle of second character.
strio.gets # => "\xB5ст"

<b>Special Record Separators</b>

Like some methods in class IO, method +gets+ honors two special record separators;
see {Special Line Separators}[https://docs.ruby-lang.org/en/master/IO.html#class-IO-label-Special+Line+Separator+Values]:

strio = StringIO.new(TEXT)
strio.gets('') # Read "paragraph" (up to empty line).
# => "First line\nSecond line\n\n"

strio = StringIO.new(TEXT)
strio.gets(nil) # "Slurp": read all.
# => "First line\nSecond line\n\nFourth line\nFifth line\n"

<b>Keyword Argument +chomp+</b>

With keyword argument +chomp+ given as +true+ (the default is +false+),
removes the trailing newline (if any) from the returned line:

strio = StringIO.new(TEXT)
strio.gets # => "First line\n"
strio.gets(chomp: true) # => "Second line"

Related: StringIO.each_line.
20 changes: 10 additions & 10 deletions ext/io/wait/io-wait.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,20 @@ Gem::Specification.new do |spec|
spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = spec.homepage

spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
`git ls-files -z`.split("\x0").reject do |f|
File.identical?(f, __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features|rakelib)/|\.(?:git|travis|circleci)|appveyor|Rakefile)})
end
end
jruby = true if Gem::Platform.new('java') =~ spec.platform or RUBY_ENGINE == 'jruby'
dir, gemspec = File.split(__FILE__)
excludes = [
*%w[:^/.git* :^/Gemfile* :^/Rakefile* :^/bin/ :^/test/ :^/rakelib/ :^*.java],
*(jruby ? %w[:^/ext/io] : %w[:^/ext/java]),
":(exclude,literal,top)#{gemspec}"
]
files = IO.popen(%w[git ls-files -z --] + excludes, chdir: dir, &:read).split("\x0")

spec.files = files
spec.bindir = "exe"
spec.executables = []
spec.require_paths = ["lib"]

jruby = true if Gem::Platform.new('java') =~ spec.platform or RUBY_ENGINE == 'jruby'
spec.files.delete_if do |f|
f.end_with?(".java") or
f.start_with?("ext/") && (jruby ^ f.start_with?("ext/java/"))
end
if jruby
spec.platform = 'java'
spec.files << "lib/io/wait.jar"
Expand Down
11 changes: 5 additions & 6 deletions ext/stringio/stringio.c
Original file line number Diff line number Diff line change
Expand Up @@ -990,10 +990,10 @@ strio_getc(VALUE self)

/*
* call-seq:
* getbyte -> byte or nil
* getbyte -> integer or nil
*
* :include: stringio/getbyte.rdoc
*
* Reads and returns the next 8-bit byte from the stream;
* see {Byte IO}[rdoc-ref:IO@Byte+IO].
*/
static VALUE
strio_getbyte(VALUE self)
Expand Down Expand Up @@ -1428,9 +1428,8 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
* gets(limit, chomp: false) -> string or nil
* gets(sep, limit, chomp: false) -> string or nil
*
* Reads and returns a line from the stream;
* assigns the return value to <tt>$_</tt>;
* see {Line IO}[rdoc-ref:IO@Line+IO].
* :include: stringio/gets.rdoc
*
*/
static VALUE
strio_gets(int argc, VALUE *argv, VALUE self)
Expand Down
8 changes: 4 additions & 4 deletions lib/rubygems/package/tar_header.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class Gem::Package::TarHeader
##
# Pack format for a tar header

PACK_FORMAT = ("a100" + # name
PACK_FORMAT = "a100" + # name
"a8" + # mode
"a8" + # uid
"a8" + # gid
Expand All @@ -71,12 +71,12 @@ class Gem::Package::TarHeader
"a32" + # gname
"a8" + # devmajor
"a8" + # devminor
"a155").freeze # prefix
"a155" # prefix

##
# Unpack format for a tar header

UNPACK_FORMAT = ("A100" + # name
UNPACK_FORMAT = "A100" + # name
"A8" + # mode
"A8" + # uid
"A8" + # gid
Expand All @@ -91,7 +91,7 @@ class Gem::Package::TarHeader
"A32" + # gname
"A8" + # devmajor
"A8" + # devminor
"A155").freeze # prefix
"A155" # prefix

attr_reader(*FIELDS)

Expand Down
6 changes: 1 addition & 5 deletions lib/uri/mailto.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,7 @@ class MailTo < Generic
HEADER_REGEXP = /\A(?<hfield>(?:%\h\h|[!$'-.0-;@-Z_a-z~])*=(?:%\h\h|[!$'-.0-;@-Z_a-z~])*)(?:&\g<hfield>)*\z/
# practical regexp for email address
# https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address
EMAIL_REGEXP = %r[\A#{
atext = %q[(?:[a-zA-Z0-9!\#$%&'*+\/=?^_`{|}~-]+)]
}(?:\.#{atext})*@#{
label = %q[(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)]
}(?:\.#{label})*\z]
EMAIL_REGEXP = /\A[a-zA-Z0-9.!\#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\z/
# :startdoc:

#
Expand Down
19 changes: 0 additions & 19 deletions test/rubygems/test_gem_package_tar_header.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,6 @@ def setup
@tar_header = Gem::Package::TarHeader.new header
end

def test_decode_in_ractor
new_header = Ractor.new(@tar_header.to_s) do |str|
Gem::Package::TarHeader.from StringIO.new str
end.value

assert_headers_equal @tar_header, new_header
end if defined?(Ractor) && Ractor.instance_methods.include?(:value)

def test_encode_in_ractor
header_bytes = @tar_header.to_s

new_header = Ractor.new(header_bytes) do |str|
header = Gem::Package::TarHeader.from StringIO.new str
header.to_s
end.value

assert_headers_equal header_bytes, new_header
end if defined?(Ractor) && Ractor.instance_methods.include?(:value)

def test_self_from
io = TempIO.new @tar_header.to_s

Expand Down
26 changes: 10 additions & 16 deletions test/uri/test_mailto.rb
Original file line number Diff line number Diff line change
Expand Up @@ -145,29 +145,23 @@ def test_check_to
u.to = 'a@valid.com'
assert_equal(u.to, 'a@valid.com')

# Invalid emails
assert_raise(URI::InvalidComponentError) do
u.to = '#1@mail.com'
end
# Intentionally allowed violations of RFC 5322
u.to = 'a..a@valid.com'
assert_equal(u.to, 'a..a@valid.com')

assert_raise(URI::InvalidComponentError) do
u.to = '@invalid.email'
end
u.to = 'hello.@valid.com'
assert_equal(u.to, 'hello.@valid.com')

assert_raise(URI::InvalidComponentError) do
u.to = '.hello@invalid.email'
end

assert_raise(URI::InvalidComponentError) do
u.to = 'hello.@invalid.email'
end
u.to = '.hello@valid.com'
assert_equal(u.to, '.hello@valid.com')

# Invalid emails
assert_raise(URI::InvalidComponentError) do
u.to = 'n.@invalid.email'
u.to = '#1@mail.com'
end

assert_raise(URI::InvalidComponentError) do
u.to = 'n..t@invalid.email'
u.to = '@invalid.email'
end

# Invalid host emails
Expand Down
7 changes: 0 additions & 7 deletions zjit/src/asm/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -779,13 +779,6 @@ pub fn imul(cb: &mut CodeBlock, opnd0: X86Opnd, opnd1: X86Opnd) {
write_rm(cb, false, true, opnd0, opnd1, None, &[0x0F, 0xAF]);
}

// Flip the operands to handle this case. This instruction has weird encoding restrictions.
(X86Opnd::Mem(_), X86Opnd::Reg(_)) => {
//REX.W + 0F AF /rIMUL r64, r/m64
// Quadword register := Quadword register * r/m64.
write_rm(cb, false, true, opnd1, opnd0, None, &[0x0F, 0xAF]);
}

_ => unreachable!()
}
}
Expand Down
18 changes: 12 additions & 6 deletions zjit/src/asm/x86_64/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,22 +228,28 @@ fn test_cqo() {
fn test_imul() {
let cb1 = compile(|cb| imul(cb, RAX, RBX));
let cb2 = compile(|cb| imul(cb, RDX, mem_opnd(64, RAX, 0)));
// Operands flipped for encoding since multiplication is commutative
let cb3 = compile(|cb| imul(cb, mem_opnd(64, RAX, 0), RDX));

assert_disasm_snapshot!(disasms!(cb1, cb2, cb3), @r"
assert_disasm_snapshot!(disasms!(cb1, cb2), @r"
0x0: imul rax, rbx
0x0: imul rdx, qword ptr [rax]
0x0: imul rdx, qword ptr [rax]
");

assert_snapshot!(hexdumps!(cb1, cb2, cb3), @r"
assert_snapshot!(hexdumps!(cb1, cb2), @r"
480fafc3
480faf10
480faf10
");
}

#[test]
#[should_panic]
fn test_imul_mem_reg() {
// imul doesn't have (Mem, Reg) encoding. Since multiplication is communicative, imul() could
// swap operands. However, x86_scratch_split may need to move the result to the output operand,
// which can be complicated if the assembler may sometimes change the result operand.
// So x86_scratch_split should be responsible for that swap, not the assembler.
compile(|cb| imul(cb, mem_opnd(64, RAX, 0), RDX));
}

#[test]
fn test_jge_label() {
let cb = compile(|cb| {
Expand Down
Loading