diff --git a/doc/format_specifications.rdoc b/doc/format_specifications.rdoc
index bdfdc249536b36..a2755256df3994 100644
--- a/doc/format_specifications.rdoc
+++ b/doc/format_specifications.rdoc
@@ -30,8 +30,9 @@ It consists of:
- A leading percent character.
- Zero or more _flags_ (each is a character).
-- An optional _width_ _specifier_ (an integer).
-- An optional _precision_ _specifier_ (a period followed by a non-negative integer).
+- An optional _width_ _specifier_ (an integer, or *).
+- An optional _precision_ _specifier_ (a period followed by a non-negative
+ integer, or *).
- A _type_ _specifier_ (a character).
Except for the leading percent character,
@@ -125,13 +126,6 @@ Left-pad with zeros instead of spaces:
sprintf('%6d', 100) # => " 100"
sprintf('%06d', 100) # => "000100"
-=== '*' Flag
-
-Use the next argument as the field width:
-
- sprintf('%d', 20, 14) # => "20"
- sprintf('%*d', 20, 14) # => " 14"
-
=== 'n$' Flag
Format the (1-based) nth argument into this field:
@@ -152,6 +146,11 @@ of the formatted field:
# Ignore if too small.
sprintf('%1d', 100) # => "100"
+If the width specifier is '*' instead of an integer, the actual minimum
+width is taken from the argument list:
+
+ sprintf('%*d', 20, 14) # => " 14"
+
== Precision Specifier
A precision specifier is a decimal point followed by zero or more
@@ -194,6 +193,11 @@ the number of characters to write:
sprintf('%s', Time.now) # => "2022-05-04 11:59:16 -0400"
sprintf('%.10s', Time.now) # => "2022-05-04"
+If the precision specifier is '*' instead of a non-negative integer,
+the actual precision is taken from the argument list:
+
+ sprintf('%.*d', 20, 1) # => "00000000000000000001"
+
== Type Specifier Details and Examples
=== Specifiers +a+ and +A+
diff --git a/io.c b/io.c
index 4ee45c13442f7c..f6daa793990899 100644
--- a/io.c
+++ b/io.c
@@ -4947,7 +4947,7 @@ rb_io_each_codepoint(VALUE io)
fptr->cbuf.off += n;
fptr->cbuf.len -= n;
rb_yield(UINT2NUM(c));
- rb_io_check_byte_readable(fptr);
+ rb_io_check_char_readable(fptr);
}
}
NEED_NEWLINE_DECORATOR_ON_READ_CHECK(fptr);
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index 3ec8726b5e45ce..0025aa5a7dd502 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -467,6 +467,24 @@ def test_each_codepoint_closed
}
end
+ def test_each_codepoint_with_ungetc
+ bug21562 = '[ruby-core:123176] [Bug #21562]'
+ with_read_pipe("") {|p|
+ p.binmode
+ p.ungetc("aa")
+ a = ""
+ p.each_codepoint { |c| a << c }
+ assert_equal("aa", a, bug21562)
+ }
+ with_read_pipe("") {|p|
+ p.set_encoding("ascii-8bit", universal_newline: true)
+ p.ungetc("aa")
+ a = ""
+ p.each_codepoint { |c| a << c }
+ assert_equal("aa", a, bug21562)
+ }
+ end
+
def test_rubydev33072
t = make_tempfile
path = t.path