From bfa6a8ddc84fffe0aef5a0f91b417167e124dbbf Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Wed, 10 Aug 2022 13:02:19 -0700 Subject: [PATCH 01/12] Only allow procs created by Symbol#to_proc to call public methods Fixes [Bug #18826] Co-authored-by: Nobuyoshi Nakada --- .../core/kernel/fixtures/warn_core_method.rb | 2 +- spec/ruby/core/symbol/to_proc_spec.rb | 27 ++++++++++++++ vm_insnhelper.c | 36 +++++++++++++++---- 3 files changed, 57 insertions(+), 8 deletions(-) diff --git a/spec/ruby/core/kernel/fixtures/warn_core_method.rb b/spec/ruby/core/kernel/fixtures/warn_core_method.rb index f5dee6b668aaed..fd825624047afa 100644 --- a/spec/ruby/core/kernel/fixtures/warn_core_method.rb +++ b/spec/ruby/core/kernel/fixtures/warn_core_method.rb @@ -1,6 +1,6 @@ raise 'should be run without RubyGems' if defined?(Gem) -def deprecated(n=1) +public def deprecated(n=1) # puts nil, caller(0), nil warn "use X instead", uplevel: n end diff --git a/spec/ruby/core/symbol/to_proc_spec.rb b/spec/ruby/core/symbol/to_proc_spec.rb index 47f2a939ab2d75..81939e0046c540 100644 --- a/spec/ruby/core/symbol/to_proc_spec.rb +++ b/spec/ruby/core/symbol/to_proc_spec.rb @@ -46,6 +46,33 @@ end end + ruby_version_is "3.2" do + it "only calls public methods" do + body = proc do + public def pub; @a << :pub end + protected def pro; @a << :pro end + private def pri; @a << :pri end + attr_reader :a + end + + @a = [] + singleton_class.class_eval(&body) + tap(&:pub) + proc{tap(&:pro)}.should raise_error(NoMethodError) + proc{tap(&:pri)}.should raise_error(NoMethodError) + @a.should == [:pub] + + @a = [] + c = Class.new(&body) + o = c.new + o.instance_variable_set(:@a, []) + o.tap(&:pub) + proc{tap(&:pro)}.should raise_error(NoMethodError) + proc{o.tap(&:pri)}.should raise_error(NoMethodError) + o.a.should == [:pub] + end + end + it "raises an ArgumentError when calling #call on the Proc without receiver" do -> { :object_id.to_proc.call diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 2c0a369a439001..1812f7ce71aead 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -3182,9 +3182,11 @@ ci_missing_reason(const struct rb_callinfo *ci) return stat; } +static VALUE vm_call_method_missing(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling); + static VALUE vm_call_symbol(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, - struct rb_calling_info *calling, const struct rb_callinfo *ci, VALUE symbol) + struct rb_calling_info *calling, const struct rb_callinfo *ci, VALUE symbol, int flags) { ASSUME(calling->argc >= 0); /* Also assumes CALLER_SETUP_ARG is already done. */ @@ -3194,9 +3196,7 @@ vm_call_symbol(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, VALUE recv = calling->recv; VALUE klass = CLASS_OF(recv); ID mid = rb_check_id(&symbol); - int flags = VM_CALL_FCALL | - VM_CALL_OPT_SEND | - (calling->kw_splat ? VM_CALL_KW_SPLAT : 0); + flags |= VM_CALL_OPT_SEND | (calling->kw_splat ? VM_CALL_KW_SPLAT : 0); if (UNLIKELY(! mid)) { mid = idMethodMissing; @@ -3243,7 +3243,29 @@ vm_call_symbol(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, { .method_missing_reason = missing_reason }, rb_callable_method_entry_with_refinements(klass, mid, NULL)); - return vm_call_method(ec, reg_cfp, calling); + if (flags & VM_CALL_FCALL) { + return vm_call_method(ec, reg_cfp, calling); + } + + const struct rb_callcache *cc = calling->cc; + VM_ASSERT(callable_method_entry_p(vm_cc_cme(cc))); + + if (vm_cc_cme(cc) != NULL) { + switch (METHOD_ENTRY_VISI(vm_cc_cme(cc))) { + case METHOD_VISI_PUBLIC: /* likely */ + return vm_call_method_each_type(ec, reg_cfp, calling); + case METHOD_VISI_PRIVATE: + vm_cc_method_missing_reason_set(cc, MISSING_PRIVATE); + case METHOD_VISI_PROTECTED: + vm_cc_method_missing_reason_set(cc, MISSING_PROTECTED); + break; + default: + VM_UNREACHABLE(vm_call_method); + } + return vm_call_method_missing(ec, reg_cfp, calling); + } + + return vm_call_method_nome(ec, reg_cfp, calling); } static VALUE @@ -3283,7 +3305,7 @@ vm_call_opt_send(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct calling->argc -= 1; DEC_SP(1); - return vm_call_symbol(ec, reg_cfp, calling, calling->ci, sym); + return vm_call_symbol(ec, reg_cfp, calling, calling->ci, sym, VM_CALL_FCALL); } } @@ -4097,7 +4119,7 @@ vm_invoke_symbol_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, VALUE symbol = VM_BH_TO_SYMBOL(block_handler); CALLER_SETUP_ARG(reg_cfp, calling, ci); calling->recv = TOPN(--calling->argc); - return vm_call_symbol(ec, reg_cfp, calling, ci, symbol); + return vm_call_symbol(ec, reg_cfp, calling, ci, symbol, 0); } } From ff42e2359bdbf37e1721a82b4cfd95b31f494f3f Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Fri, 3 Jun 2022 18:15:56 -0700 Subject: [PATCH 02/12] Revert "Add {Method,UnboundMethod}#{public?,private?,protected?}" This reverts commit 27278150685e738f84105d09843d3ba371146c7a and 58dc8bf8f15df9a33d191074e8a5d4946a3d59d5. Visibility is an attribute of the method entry in a class, not an attribute of the Method object. Fixes [#18729] Fixes [#18751] Fixes [#18435] --- proc.c | 60 +--------------------------------------- test/ruby/test_method.rb | 53 ++--------------------------------- 2 files changed, 3 insertions(+), 110 deletions(-) diff --git a/proc.c b/proc.c index a525562230b3c8..c234ed3f9365b7 100644 --- a/proc.c +++ b/proc.c @@ -40,7 +40,6 @@ struct METHOD { const VALUE iclass; const rb_method_entry_t * const me; /* for bound methods, `me' should be rb_callable_method_entry_t * */ - rb_method_visibility_t visibility; }; VALUE rb_cUnboundMethod; @@ -1664,7 +1663,6 @@ mnew_missing(VALUE klass, VALUE obj, ID id, VALUE mclass) me = rb_method_entry_create(id, klass, METHOD_VISI_UNDEF, def); RB_OBJ_WRITE(method, &data->me, me); - data->visibility = METHOD_ENTRY_VISI(me); return method; } @@ -1722,7 +1720,6 @@ mnew_internal(const rb_method_entry_t *me, VALUE klass, VALUE iclass, RB_OBJ_WRITE(method, &data->klass, klass); RB_OBJ_WRITE(method, &data->iclass, iclass); RB_OBJ_WRITE(method, &data->me, me); - data->visibility = visi; return method; } @@ -1820,7 +1817,6 @@ method_eq(VALUE method, VALUE other) if (!rb_method_entry_eq(m1->me, m2->me) || klass1 != klass2 || - m1->visibility != m2->visibility || m1->klass != m2->klass || m1->recv != m2->recv) { return Qfalse; @@ -1874,7 +1870,6 @@ method_unbind(VALUE obj) RB_OBJ_WRITE(method, &data->klass, orig->klass); RB_OBJ_WRITE(method, &data->iclass, orig->iclass); RB_OBJ_WRITE(method, &data->me, rb_method_entry_clone(orig->me)); - data->visibility = orig->visibility; return method; } @@ -2390,7 +2385,6 @@ method_clone(VALUE self) RB_OBJ_WRITE(clone, &data->klass, orig->klass); RB_OBJ_WRITE(clone, &data->iclass, orig->iclass); RB_OBJ_WRITE(clone, &data->me, rb_method_entry_clone(orig->me)); - data->visibility = orig->visibility; return clone; } @@ -2641,7 +2635,6 @@ umethod_bind(VALUE method, VALUE recv) RB_OBJ_WRITE(method, &bound->klass, klass); RB_OBJ_WRITE(method, &bound->iclass, iclass); RB_OBJ_WRITE(method, &bound->me, me); - bound->visibility = data->visibility; return method; } @@ -2677,7 +2670,7 @@ umethod_bind_call(int argc, VALUE *argv, VALUE method) VALUE methclass, klass, iclass; const rb_method_entry_t *me; convert_umethod_to_method_components(data, recv, &methclass, &klass, &iclass, &me); - struct METHOD bound = { recv, klass, 0, me, METHOD_ENTRY_VISI(me) }; + struct METHOD bound = { recv, klass, 0, me }; return call_method_data(ec, &bound, argc, argv, passed_procval, RB_PASS_CALLED_KEYWORDS); } @@ -3354,51 +3347,6 @@ method_super_method(VALUE method) return mnew_internal(me, me->owner, iclass, data->recv, mid, rb_obj_class(method), FALSE, FALSE); } -/* - * call-seq: - * meth.public? -> true or false - * - * Returns whether the method is public. - */ - -static VALUE -method_public_p(VALUE method) -{ - const struct METHOD *data; - TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); - return RBOOL(data->visibility == METHOD_VISI_PUBLIC); -} - -/* - * call-seq: - * meth.protected? -> true or false - * - * Returns whether the method is protected. - */ - -static VALUE -method_protected_p(VALUE method) -{ - const struct METHOD *data; - TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); - return RBOOL(data->visibility == METHOD_VISI_PROTECTED); -} - -/* - * call-seq: - * meth.private? -> true or false - * - * Returns whether the method is private. - */ - -static VALUE -method_private_p(VALUE method) -{ - const struct METHOD *data; - TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); - return RBOOL(data->visibility == METHOD_VISI_PRIVATE); -} - /* * call-seq: * local_jump_error.exit_value -> obj @@ -4339,9 +4287,6 @@ Init_Proc(void) rb_define_method(rb_cMethod, "source_location", rb_method_location, 0); rb_define_method(rb_cMethod, "parameters", rb_method_parameters, 0); rb_define_method(rb_cMethod, "super_method", method_super_method, 0); - rb_define_method(rb_cMethod, "public?", method_public_p, 0); - rb_define_method(rb_cMethod, "protected?", method_protected_p, 0); - rb_define_method(rb_cMethod, "private?", method_private_p, 0); rb_define_method(rb_mKernel, "method", rb_obj_method, 1); rb_define_method(rb_mKernel, "public_method", rb_obj_public_method, 1); rb_define_method(rb_mKernel, "singleton_method", rb_obj_singleton_method, 1); @@ -4365,9 +4310,6 @@ Init_Proc(void) rb_define_method(rb_cUnboundMethod, "source_location", rb_method_location, 0); rb_define_method(rb_cUnboundMethod, "parameters", rb_method_parameters, 0); rb_define_method(rb_cUnboundMethod, "super_method", method_super_method, 0); - rb_define_method(rb_cUnboundMethod, "public?", method_public_p, 0); - rb_define_method(rb_cUnboundMethod, "protected?", method_protected_p, 0); - rb_define_method(rb_cUnboundMethod, "private?", method_private_p, 0); /* Module#*_method */ rb_define_method(rb_cModule, "instance_method", rb_mod_instance_method, 1); diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb index 83e499913a4bb4..56e94493d9860c 100644 --- a/test/ruby/test_method.rb +++ b/test/ruby/test_method.rb @@ -199,11 +199,6 @@ def m.foo; end assert_equal(o.method(:foo), o.method(:foo)) assert_equal(o.method(:foo), o.method(:bar)) assert_not_equal(o.method(:foo), o.method(:baz)) - - class << o - private :bar - end - assert_not_equal(o.method(:foo), o.method(:bar)) end def test_hash @@ -330,8 +325,8 @@ class << PUBLIC_SINGLETON_TEST def PUBLIC_SINGLETON_TEST.def; end end def test_define_singleton_method_public - assert_equal(true, PUBLIC_SINGLETON_TEST.method(:dsm).public?) - assert_equal(true, PUBLIC_SINGLETON_TEST.method(:def).public?) + assert_nil(PUBLIC_SINGLETON_TEST.dsm) + assert_nil(PUBLIC_SINGLETON_TEST.def) end def test_define_singleton_method_no_proc @@ -1197,50 +1192,6 @@ def foo assert_nil(super_method) end - def test_method_visibility_predicates - v = Visibility.new - assert_equal(true, v.method(:mv1).public?) - assert_equal(true, v.method(:mv2).private?) - assert_equal(true, v.method(:mv3).protected?) - assert_equal(false, v.method(:mv2).public?) - assert_equal(false, v.method(:mv3).private?) - assert_equal(false, v.method(:mv1).protected?) - end - - def test_unbound_method_visibility_predicates - assert_equal(true, Visibility.instance_method(:mv1).public?) - assert_equal(true, Visibility.instance_method(:mv2).private?) - assert_equal(true, Visibility.instance_method(:mv3).protected?) - assert_equal(false, Visibility.instance_method(:mv2).public?) - assert_equal(false, Visibility.instance_method(:mv3).private?) - assert_equal(false, Visibility.instance_method(:mv1).protected?) - end - - class VisibilitySub < Visibility - protected :mv1 - public :mv2 - private :mv3 - end - - def test_method_visibility_predicates_with_subclass_visbility_change - v = VisibilitySub.new - assert_equal(false, v.method(:mv1).public?) - assert_equal(false, v.method(:mv2).private?) - assert_equal(false, v.method(:mv3).protected?) - assert_equal(true, v.method(:mv2).public?) - assert_equal(true, v.method(:mv3).private?) - assert_equal(true, v.method(:mv1).protected?) - end - - def test_unbound_method_visibility_predicates_with_subclass_visbility_change - assert_equal(false, VisibilitySub.instance_method(:mv1).public?) - assert_equal(false, VisibilitySub.instance_method(:mv2).private?) - assert_equal(false, VisibilitySub.instance_method(:mv3).protected?) - assert_equal(true, VisibilitySub.instance_method(:mv2).public?) - assert_equal(true, VisibilitySub.instance_method(:mv3).private?) - assert_equal(true, VisibilitySub.instance_method(:mv1).protected?) - end - def rest_parameter(*rest) rest end From 9fc401b689e64dde5fc7cc56c734d5cddd6aa6e1 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Wed, 10 Aug 2022 16:18:27 -0500 Subject: [PATCH 03/12] [ruby/rdoc] Treat text markup (italic, bold, monofont) as blocks (https://github.com/ruby/rdoc/pull/911) https://github.com/ruby/rdoc/commit/dc88f1b425 --- doc/rdoc/markup_reference.rb | 367 ++++++++++++++++++++++++----------- 1 file changed, 253 insertions(+), 114 deletions(-) diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb index c59f12cfe3c59e..b3d1d97f4f61be 100644 --- a/doc/rdoc/markup_reference.rb +++ b/doc/rdoc/markup_reference.rb @@ -51,23 +51,37 @@ # # === Blocks # -# It's convenient to think of markup input as a sequence of _blocks_, -# such as: -# -# - {Paragraphs}[rdoc-ref:RDoc::MarkupReference@Paragraphs]. -# - {Verbatim text blocks}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks]. -# - {Code blocks}[rdoc-ref:RDoc::MarkupReference@Code+Blocks]. -# - {Block quotes}[rdoc-ref:RDoc::MarkupReference@Block+Quotes]. -# - {Bullet lists}[rdoc-ref:RDoc::MarkupReference@Bullet+Lists]. -# - {Numbered lists}[rdoc-ref:RDoc::MarkupReference@Numbered+Lists]. -# - {Lettered lists}[rdoc-ref:RDoc::MarkupReference@Lettered+Lists]. -# - {Labeled lists}[rdoc-ref:RDoc::MarkupReference@Labeled+Lists]. -# - {Headings}[rdoc-ref:RDoc::MarkupReference@Headings]. -# - {Horizontal rules}[rdoc-ref:RDoc::MarkupReference@Horizontal+Rules]. -# - {Directives}[rdoc-ref:RDoc::MarkupReference@Directives]. -# -# All of these except paragraph blocks are distinguished by indentation, -# or by unusual initial or embedded characters. +# It's convenient to think of \RDoc markup input as a sequence of _blocks_ +# of various types (details at the links): +# +# - {Paragraph}[rdoc-ref:RDoc::MarkupReference@Paragraphs]: +# an ordinary paragraph. +# - {Verbatim text block}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks]: +# a block of text to be rendered literally. +# - {Code block}[rdoc-ref:RDoc::MarkupReference@Code+Blocks]: +# a verbatim text block containing Ruby code, +# to be rendered with code highlighting. +# - {Block quote}[rdoc-ref:RDoc::MarkupReference@Block+Quotes]: +# a longish quoted passage, to be rendered with indentation +# instead of quote marks. +# - {List}[rdoc-ref:RDoc::MarkupReference@Lists]: items for +# a bullet list, numbered list, lettered list, or labeled list. +# - {Heading}[rdoc-ref:RDoc::MarkupReference@Headings]: +# a section heading. +# - {Horizontal rule}[rdoc-ref:RDoc::MarkupReference@Horizontal+Rules]: +# a line across the rendered page. +# - {Directive}[rdoc-ref:RDoc::MarkupReference@Directives]: +# various special directions for the rendering. +# - {Text Markup}[rdoc-ref:RDoc:MarkupReference@Text+Markup]: +# text to be rendered in italic, bold, or monofont. +# +# About the blocks: +# +# - Except for a paragraph, a block is distinguished by its indentation, +# or by unusual initial or embedded characters. +# - Any block may appear independently +# (that is, not nested in another block); +# some blocks may be nested, as detailed below. # # ==== Paragraphs # @@ -98,12 +112,13 @@ # # A paragraph may contain nested blocks, including: # -# - Verbatim text blocks. -# - Code blocks. -# - Block quotes. -# - Lists of any type. -# - Headings. -# - Horizontal rules. +# - {Verbatim text blocks}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks]. +# - {Code blocks}[rdoc-ref:RDoc::MarkupReference@Code+Blocks]. +# - {Block quotes}[rdoc-ref:RDoc::MarkupReference@Block+Quotes]. +# - {Lists}[rdoc-ref:RDoc::MarkupReference@Lists]. +# - {Headings}[rdoc-ref:RDoc::MarkupReference@Headings]. +# - {Horizontal rules}[rdoc-ref:RDoc::MarkupReference@Horizontal+Rules]. +# - {Text Markup}[rdoc-ref:RDoc:MarkupReference@Text+Markup]. # # ==== Verbatim Text Blocks # @@ -140,6 +155,9 @@ # # This is not verbatim text. # +# A verbatim text block may not contain nested blocks of any kind +# -- it's verbatim. +# # ==== Code Blocks # # A special case of verbatim text is the code block, @@ -173,6 +191,9 @@ # Pro tip: If your indented Ruby code does not get highlighted, # it may contain a syntax error. # +# A code block may not contain nested blocks of any kind +# -- it's verbatim. +# # ==== Block Quotes # # You can use the characters >>> (unindented), @@ -181,6 +202,7 @@ # # Example input: # +# Here's a block quote: # >>> # Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer # commodo quam iaculis massa posuere, dictum fringilla justo pulvinar. @@ -194,27 +216,30 @@ # Rendered HTML: # # >>> -# Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer -# commodo quam iaculis massa posuere, dictum fringilla justo pulvinar. -# Quisque turpis erat, pharetra eu dui at, sollicitudin accumsan nulla. +# Here's a block quote: +# >>> +# Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer +# commodo quam iaculis massa posuere, dictum fringilla justo pulvinar. +# Quisque turpis erat, pharetra eu dui at, sollicitudin accumsan nulla. # -# Aenean congue ligula eu ligula molestie, eu pellentesque purus -# faucibus. In id leo non ligula condimentum lobortis. Duis vestibulum, -# diam in pellentesque aliquet, mi tellus placerat sapien, id euismod -# purus magna ut tortor. +# Aenean congue ligula eu ligula molestie, eu pellentesque purus +# faucibus. In id leo non ligula condimentum lobortis. Duis vestibulum, +# diam in pellentesque aliquet, mi tellus placerat sapien, id euismod +# purus magna ut tortor. +# +# Note that, unlike verbatim text, single newlines are not honored, +# but that a double newline begins a new paragraph in the block quote. # # A block quote may contain nested blocks, including: # # - Other block quotes. -# - Paragraphs. -# - Verbatim text blocks. -# - Code blocks. -# - Lists of any type. -# - Headings. -# - Horizontal rules. -# -# Note that, unlike verbatim text, single newlines are not honored, -# but that a double newline begins a new paragraph in the block quote. +# - {Paragraphs}[rdoc-ref:RDoc::MarkupReference@Paragraphs]. +# - {Verbatim text blocks}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks]. +# - {Code blocks}[rdoc-ref:RDoc::MarkupReference@Code+Blocks]. +# - {Lists}[rdoc-ref:RDoc::MarkupReference@Lists]. +# - {Headings}[rdoc-ref:RDoc::MarkupReference@Headings]. +# - {Horizontal rules}[rdoc-ref:RDoc::MarkupReference@Horizontal+Rules]. +# - {Text Markup}[rdoc-ref:RDoc:MarkupReference@Text+Markup]. # # ==== Lists # @@ -240,12 +265,13 @@ # A list item may contain nested blocks, including: # # - Other lists of any type. -# - Paragraphs. -# - Verbatim text blocks. -# - Code blocks. -# - Block quotes. -# - Headings. -# - Horizontal rules. +# - {Paragraphs}[rdoc-ref:RDoc::MarkupReference@Paragraphs]. +# - {Verbatim text blocks}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks]. +# - {Code blocks}[rdoc-ref:RDoc::MarkupReference@Code+Blocks]. +# - {Block quotes}[rdoc-ref:RDoc::MarkupReference@Block+Quotes]. +# - {Headings}[rdoc-ref:RDoc::MarkupReference@Headings]. +# - {Horizontal rules}[rdoc-ref:RDoc::MarkupReference@Horizontal+Rules]. +# - {Text Markup}[rdoc-ref:RDoc:MarkupReference@Text+Markup]. # # ===== Bullet Lists # @@ -370,30 +396,29 @@ # # ============Still a Heading (Level 6) # # \== Not a Heading # +# A heading may contain only one type of nested block: +# +# - {Text Markup}[rdoc-ref:RDoc:MarkupReference@Text+Markup]. +# # ==== Horizontal Rules # -# A horizontal rule begins with three or more hyphens. +# A horizontal rule consists of a line with three or more hyphens +# and nothing more. # # Example input: # -# # ------ -# # Stuff between. -# # -# # \--- Not a horizontal rule. -# # -# # -- Also not a horizontal rule. -# # -# # --- +# --- +# --- Not a horizontal rule. +# +# -- Also not a horizontal rule. +# --- # # Rendered HTML: # >>> -# ------ -# Stuff between. -# -# \--- Not a horizontal rule. +# --- +# --- Not a horizontal rule. # # -- Also not a horizontal rule. -# # --- # # ==== Directives @@ -584,83 +609,197 @@ # # For C code, the directive may appear in a stand-alone comment # -# === Text Markup +# ==== Text Markup # -# Text in a paragraph, list item (any type), or heading -# may have markup formatting. +# Text markup is metatext that marks text as: # -# ==== Italic +# - Italic. +# - Bold. +# - Monofont. # -# A single word may be italicized by prefixed and suffixed underscores. +# Text markup may contain only one type of nested block: # -# Examples: +# - More text markup: +# italic, bold, monofont. # -# # _Word_ in paragraph. -# # - _Word_ in bullet list item. -# # 1. _Word_ in numbered list item. -# # a. _Word_ in lettered list item. -# # [_word_] _Word_ in labeled list item. -# # ====== _Word_ in heading +# ===== Italic # -# Any text may be italicized via HTML tag +i+ or +em+. +# Text may be marked as italic via HTML tag or . # -# Examples: +# Example input: # -# # Two words in paragraph. -# # - Two words in bullet list item. -# # 1. Two words in numbered list item. -# # a. Two words in lettered list item. -# # [Two words] Two words in labeled list item. -# # ====== Two words in heading +# Two words in a paragraph. # -# ==== Bold +# >>> +# Two words in a block quote. # -# A single word may be made bold by prefixed and suffixed asterisks. +# - Two words in a bullet list item. # -# Examples: +# ====== Two words in a Heading # -# # *Word* in paragraph. -# # - *Word* in bullet list item. -# # 1. *Word* in numbered list item. -# # a. *Word* in lettered list item. -# # [*word*] *Word* in labeled list item. -# # ====== *Word* in heading +# Italicized passage containing *bold* and +monofont+. # -# Any text may be made bold via HTML tag +b+. +# Rendered HTML: +# >>> +# Two words in a paragraph. # -# Examples: +# >>> +# Two words in a block quote. # -# # Two words in paragraph. -# # - Two words in bullet list item. -# # 1. Two words in numbered list item. -# # a. Two words in lettered list item. -# # [Two words] Two words in labeled list item. -# # ====== Two words in heading +# - Two words in a bullet list item. # -# ==== Monofont +# ====== Two words in a Heading # -# A single word may be made monofont -- sometimes called "typewriter font" -- -# by prefixed and suffixed plus-signs. +# Italicized passage containing *bold* and +monofont+. # -# Examples: +# A single word may be italicized via a shorthand: +# prefixed and suffixed underscores. # -# # +Word+ in paragraph. -# # - +Word+ in bullet list item. -# # 1. +Word+ in numbered list item. -# # a. +Word+ in lettered list item. -# # [+word+] +Word+ in labeled list item. -# # ====== +Word+ in heading +# Example input: # -# Any text may be made monofont via HTML tag +tt+ or +code+. +# _Word_ in a paragraph. # -# Examples: +# >>> +# _Word_ in a block quote. +# +# - _Word_ in a bullet list item. +# +# [_word_] _Word_ in a labeled list item. +# +# ====== _Word_ in a Heading +# +# Rendered HTML: +# >>> +# _Word_ in a paragraph. +# +# >>> +# _Word_ in a block quote. +# +# - _Word_ in a bullet list item. +# +# [_word_] _Word_ in a labeled list item. +# +# ====== _Word_ in a Heading +# +# ===== Bold +# +# Text may be marked as bold via HTML tag . +# +# Example input: +# +# Two words in a paragraph. +# +# >>> +# Two words in a block quote. +# +# - Two words in a bullet list item. +# +# ====== Two words in a Heading +# +# Bold passage containing _italics_ and +monofont+. +# +# Rendered HTML: +# +# >>> +# Two words in a paragraph. +# +# >>> +# Two words in a block quote. +# +# - Two words in a bullet list item. +# +# ====== Two words in a Heading +# +# Bold passage containing _italics_ and +monofont+. +# +# A single word may be made bold via a shorthand: +# prefixed and suffixed asterisks. +# +# Example input: +# +# *Word* in a paragraph. +# +# >>> +# *Word* in a block quote. +# +# - *Word* in a bullet list item. +# +# [*word*] *Word* in a labeled list item. +# +# ===== *Word* in a Heading +# +# Rendered HTML: +# +# >>> +# *Word* in a paragraph. +# +# >>> +# *Word* in a block quote. +# +# - *Word* in a bullet list item. +# +# [*word*] *Word* in a labeled list item. +# +# ===== *Word* in a Heading +# +# ===== Monofont +# +# Text may be marked as monofont +# -- sometimes called 'typewriter font' -- +# via HTML tag or . +# +# Example input: +# +# Two words in a paragraph. +# +# >>> +# Two words in a block quote. +# +# - Two words in a bullet list item. +# +# ====== Two words in heading +# +# Monofont passage containing _italics_ and *bold*. +# +# Rendered HTML: +# +# >>> +# Two words in a paragraph. +# +# >>> +# Two words in a block quote. +# +# - Two words in a bullet list item. +# +# ====== Two words in heading +# +# Monofont passage containing _italics_ and *bold*. +# +# A single word may be made monofont by a shorthand: +# prefixed and suffixed plus-signs. +# +# Example input: +# +# +Word+ in a paragraph. +# +# >>> +# +Word+ in a block quote. +# +# - +Word+ in a bullet list item. +# +# ====== +Word+ in a Heading +# +# Rendered HTML: +# +# >>> +# +Word+ in a paragraph. +# +# >>> +# +Word+ in a block quote. +# +# - +Word+ in a bullet list item. # -# # Two words in paragraph. -# # - Two words in bullet list item. -# # 1. Two words in numbered list item. -# # a. Two words in lettered list item. -# # [Two words] Two words in labeled list item. -# # ====== Two words in heading +# ====== +Word+ in a Heading # # ==== Escaping Text Markup # From 74d95744bdb9cf47b8fa07b9a9938c323658d9b9 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 11 Aug 2022 11:02:28 +0900 Subject: [PATCH 04/12] Add `--enable-devel` configure option Since `RUBY_DEVEL` in cppflags has no effect in the configure script and makefiles. --- .github/workflows/compilers.yml | 2 +- configure.ac | 10 +++++++--- template/Makefile.in | 4 +++- win32/configure.bat | 12 ++++++++++++ win32/setup.mak | 4 +++- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/.github/workflows/compilers.yml b/.github/workflows/compilers.yml index bd082039b316b1..8ef04f1ef233d2 100644 --- a/.github/workflows/compilers.yml +++ b/.github/workflows/compilers.yml @@ -147,6 +147,7 @@ jobs: - { name: disable-dln, env: { append_configure: '--disable-dln' } } - { name: enable-mkmf-verbose, env: { append_configure: '--enable-mkmf-verbose' } } - { name: disable-rubygems, env: { append_configure: '--disable-rubygems' } } + - { name: RUBY_DEVEL, env: { append_configure: '--enable-devel' } } - { name: OPT_THREADED_CODE=1, env: { cppflags: '-DOPT_THREADED_CODE=1' } } - { name: OPT_THREADED_CODE=2, env: { cppflags: '-DOPT_THREADED_CODE=2' } } @@ -154,7 +155,6 @@ jobs: - { name: NDEBUG, env: { cppflags: '-DNDEBUG' } } - { name: RUBY_DEBUG, env: { cppflags: '-DRUBY_DEBUG' } } - - { name: RUBY_DEVEL, env: { cppflags: '-DRUBY_DEVEL' } } # - { name: ARRAY_DEBUG, env: { cppflags: '-DARRAY_DEBUG' } } # - { name: BIGNUM_DEBUG, env: { cppflags: '-DBIGNUM_DEBUG' } } # - { name: CCAN_LIST_DEBUG, env: { cppflags: '-DCCAN_LIST_DEBUG' } } diff --git a/configure.ac b/configure.ac index 575bdf663155fd..bc21c262922161 100644 --- a/configure.ac +++ b/configure.ac @@ -622,8 +622,13 @@ AS_IF([test "$fdeclspec" = yes], [ RUBY_APPEND_OPTIONS(CXXFLAGS, -fdeclspec) ]) -AS_IF([test "x$RUBY_DEVEL" != xyes], [RUBY_DEVEL=no]) -particular_werror_flags=$RUBY_DEVEL +AC_ARG_ENABLE(devel, + AS_HELP_STRING([--enable-devel], [enable development build]), + [RUBY_DEVEL=$enableval], + [AS_IF([test "x${RUBY_DEVEL-no}" != xyes], [RUBY_DEVEL=])] +)dnl +AC_SUBST(RUBY_DEVEL) +particular_werror_flags=${RUBY_DEVEL:-no} AC_ARG_ENABLE(werror, AS_HELP_STRING([--disable-werror], [don't make warnings into errors @@ -867,7 +872,6 @@ AS_IF([test "$GCC" = yes], [ test "${debugflags+set}" || {RUBY_TRY_CFLAGS(-g3, [debugflags=-g3])} ]) test $ac_cv_prog_cc_g = yes && : ${debugflags=-g} -AS_IF([test "x$RUBY_DEVEL" = xyes], [RUBY_APPEND_OPTION(XCFLAGS, -DRUBY_DEVEL=1)]) AS_IF([test "$GCC" = ""], [ AS_CASE(["$target_os"],[aix*],[warnflags="$warnflags -qinfo=por" rb_cv_warnflags="$rb_cv_warnflags -qinfo=por"]) diff --git a/template/Makefile.in b/template/Makefile.in index a8581260b99147..756af363e4ba8e 100644 --- a/template/Makefile.in +++ b/template/Makefile.in @@ -89,7 +89,9 @@ optflags = @optflags@ debugflags = @debugflags@ warnflags = @warnflags@ @strict_warnflags@ cppflags = @cppflags@ -XCFLAGS = @XCFLAGS@ $(INCFLAGS) +RUBY_DEVEL = @RUBY_DEVEL@ # "yes" or empty +_RUBY_DEVEL_enabled = $(RUBY_DEVEL:no=) +XCFLAGS = @XCFLAGS@ $(INCFLAGS) $(_RUBY_DEVEL_enabled:yes=-DRUBY_DEVEL=1) USE_RUBYGEMS = @USE_RUBYGEMS@ USE_RUBYGEMS_ = $(USE_RUBYGEMS:yes=) CPPFLAGS = @CPPFLAGS@ $(USE_RUBYGEMS_:no=-DDISABLE_RUBYGEMS=1) diff --git a/win32/configure.bat b/win32/configure.bat index 573f8bf0e581c3..4602b41ec599a2 100755 --- a/win32/configure.bat +++ b/win32/configure.bat @@ -34,6 +34,8 @@ if "%1" == "--enable-install-static-library" goto :enable-lib if "%1" == "--disable-install-static-library" goto :disable-lib if "%1" == "--enable-debug-env" goto :enable-debug-env if "%1" == "--disable-debug-env" goto :disable-debug-env +if "%1" == "--enable-devel" goto :enable-devel +if "%1" == "--disable-devel" goto :disable-devel if "%1" == "--enable-rubygems" goto :enable-rubygems if "%1" == "--disable-rubygems" goto :disable-rubygems if "%1" == "--enable-mjit-support" goto :enable-mjit-support @@ -143,6 +145,16 @@ goto :loop ; echo>>confargs.tmp %1 \ shift goto :loop ; +:enable-devel + echo>> ~tmp~.mak "RUBY_DEVEL=yes" \ + echo>>confargs.tmp %1 \ + shift +goto :loop ; +:disable-devel + echo>> ~tmp~.mak "RUBY_DEVEL=no" \ + echo>>confargs.tmp %1 \ + shift +goto :loop ; :enable-rubygems echo>> ~tmp~.mak "USE_RUBYGEMS=yes" \ echo>>confargs.tmp %1 \ diff --git a/win32/setup.mak b/win32/setup.mak index c84d4066eabbdc..39323c61c2464f 100644 --- a/win32/setup.mak +++ b/win32/setup.mak @@ -80,6 +80,9 @@ $(BANG)else HAVE_BASERUBY = no $(BANG)endif << +!if "$(RUBY_DEVEL)" == "yes" + RUBY_DEVEL = yes +!endif !if "$(GIT)" != "" @echo GIT = $(GIT)>> $(MAKEFILE) !endif @@ -197,7 +200,6 @@ echo MINOR = RUBY_VERSION_MINOR echo TEENY = RUBY_VERSION_TEENY echo ABI_VERSION = RUBY_ABI_VERSION #if defined RUBY_PATCHLEVEL && RUBY_PATCHLEVEL < 0 -echo RUBY_DEVEL = yes #endif set /a MSC_VER = _MSC_VER #if _MSC_VER >= 1920 From 26054c74619d36b2781e872fad15a1a0bfab1be1 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 11 Aug 2022 15:21:03 +0900 Subject: [PATCH 05/12] Fix paths of exts.mk to clean exts.mk files are one level under the top of extension directories. --- template/exts.mk.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/exts.mk.tmpl b/template/exts.mk.tmpl index c5f8478d76d79c..5595a08da1d1dd 100644 --- a/template/exts.mk.tmpl +++ b/template/exts.mk.tmpl @@ -154,7 +154,7 @@ ext/extinit.<%=objext%>: % end $(Q)<%= submake %><%=mflags%> V=$(V) $(@F) % if /^(dist|real)clean$/ =~ tgt - $(Q)$(RM) $(@D)/exts.mk + $(Q)$(RM) <%=t[%r[\A(?:\.[^/]+/)?(?:[^/]+/){2}]]%>exts.mk $(Q)$(RMDIRS) $(@D) % end % end From 0c9803b0fdfd17981bd9f59767adab0207c3a74d Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 11 Aug 2022 17:09:17 +0900 Subject: [PATCH 06/12] The "gems" build directory was rename as ".bundle" --- common.mk | 12 ++++++------ template/Makefile.in | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/common.mk b/common.mk index 7e7e0bb67a8ad2..9f89e0ec8af26c 100644 --- a/common.mk +++ b/common.mk @@ -687,18 +687,18 @@ realclean-platform: distclean-platform realclean-spec: distclean-spec realclean-rubyspec: realclean-spec -clean-ext:: ext/clean gems/clean timestamp/clean -distclean-ext:: ext/distclean gems/distclean timestamp/distclean -realclean-ext:: ext/realclean gems/realclean timestamp/realclean +clean-ext:: ext/clean .bundle/clean timestamp/clean +distclean-ext:: ext/distclean .bundle/distclean timestamp/distclean +realclean-ext:: ext/realclean .bundle/realclean timestamp/realclean ext/clean.mk ext/distclean.mk ext/realclean.mk:: ext/clean:: ext/clean.mk ext/distclean:: ext/distclean.mk ext/realclean:: ext/realclean.mk -timestamp/clean:: ext/clean gems/clean -timestamp/distclean:: ext/distclean gems/distclean -timestamp/realclean:: ext/realclean gems/realclean +timestamp/clean:: ext/clean .bundle/clean +timestamp/distclean:: ext/distclean .bundle/distclean +timestamp/realclean:: ext/realclean .bundle/realclean timestamp/clean timestamp/distclean timestamp/realclean:: $(Q)$(RM) $(TIMESTAMPDIR)/.*.time $(TIMESTAMPDIR)/$(arch)/.time diff --git a/template/Makefile.in b/template/Makefile.in index 756af363e4ba8e..09d69c8d9ccc13 100644 --- a/template/Makefile.in +++ b/template/Makefile.in @@ -532,12 +532,12 @@ ext/clean.mk ext/distclean.mk ext/realclean.mk:: ext/clean:: ext/clean.sub ext/distclean:: ext/distclean.sub ext/realclean:: ext/realclean.sub -gems/clean:: gems/clean.sub -gems/distclean:: gems/distclean.sub -gems/realclean:: gems/realclean.sub +.bundle/clean:: .bundle/clean.sub +.bundle/distclean:: .bundle/distclean.sub +.bundle/realclean:: .bundle/realclean.sub ext/clean.sub ext/distclean.sub ext/realclean.sub \ -gems/clean.sub gems/distclean.sub gems/realclean.sub:: +.bundle/clean.sub .bundle/distclean.sub .bundle/realclean.sub:: $(Q) set dummy `echo "${EXTS}" | tr , ' '`; shift; \ test "$$#" = 0 && set .; \ set dummy `\ @@ -553,7 +553,7 @@ gems/clean.sub gems/distclean.sub gems/realclean.sub:: fi; \ done || true -ext/distclean ext/realclean gems/distclean gems/realclean:: +ext/distclean ext/realclean .bundle/distclean .bundle/realclean:: $(Q) set dummy `echo "${EXTS}" | tr , ' '`; shift; \ test "$$#" = 0 && set .; \ cd $(@D) 2>/dev/null && \ From 32d1ce96e09773e809d575c17b916012d88d6ffc Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 11 Aug 2022 17:42:56 +0900 Subject: [PATCH 07/12] Fix race conditions when cleaning extensions Clean built directories by `make distclean`, and then clean leftover makefiles for skipped extensions. --- template/Makefile.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/template/Makefile.in b/template/Makefile.in index 09d69c8d9ccc13..7968619f9a1a16 100644 --- a/template/Makefile.in +++ b/template/Makefile.in @@ -536,6 +536,10 @@ ext/realclean:: ext/realclean.sub .bundle/distclean:: .bundle/distclean.sub .bundle/realclean:: .bundle/realclean.sub +ext/clean.sub .bundle/clean.sub:: ext/clean.mk +ext/distclean.sub .bundle/distclean.sub:: ext/distclean.mk +ext/realclean.sub .bundle/realclean.sub:: ext/realclean.mk + ext/clean.sub ext/distclean.sub ext/realclean.sub \ .bundle/clean.sub .bundle/distclean.sub .bundle/realclean.sub:: $(Q) set dummy `echo "${EXTS}" | tr , ' '`; shift; \ From cfb9624460a295e4e1723301486d89058c228e07 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Thu, 11 Aug 2022 03:16:49 -0700 Subject: [PATCH 08/12] Fix Array#[] with ArithmeticSequence with negative steps (#5739) * Fix Array#[] with ArithmeticSequence with negative steps Previously, Array#[] when called with an ArithmeticSequence with a negative step did not handle all cases correctly, especially cases involving infinite ranges, inverted ranges, and/or exclusive ends. Fixes [Bug #18247] * Add Array#slice tests for ArithmeticSequence with negative step to test_array Add tests of rb_arithmetic_sequence_beg_len_step C-API function. * Fix ext/-test-/arith_seq/beg_len_step/depend * Rename local variables * Fix a variable name Co-authored-by: Kenta Murata <3959+mrkn@users.noreply.github.com> --- array.c | 5 +- enumerator.c | 7 + .../arith_seq/beg_len_step/beg_len_step.c | 19 +++ ext/-test-/arith_seq/beg_len_step/depend | 161 ++++++++++++++++++ ext/-test-/arith_seq/beg_len_step/extconf.rb | 2 + spec/ruby/core/array/shared/slice.rb | 96 +++++++++++ .../arith_seq/test_arith_seq_beg_len_step.rb | 52 ++++++ test/ruby/test_array.rb | 90 ++++++++++ 8 files changed, 431 insertions(+), 1 deletion(-) create mode 100644 ext/-test-/arith_seq/beg_len_step/beg_len_step.c create mode 100644 ext/-test-/arith_seq/beg_len_step/depend create mode 100644 ext/-test-/arith_seq/beg_len_step/extconf.rb create mode 100644 test/-ext-/arith_seq/test_arith_seq_beg_len_step.rb diff --git a/array.c b/array.c index b2ebf3c0e9ebee..793a53f17b24b2 100644 --- a/array.c +++ b/array.c @@ -1373,13 +1373,16 @@ ary_make_partial_step(VALUE ary, VALUE klass, long offset, long len, long step) const VALUE *values = RARRAY_CONST_PTR_TRANSIENT(ary); const long orig_len = len; - if ((step > 0 && step >= len) || (step < 0 && (step < -len))) { + if (step > 0 && step >= len) { VALUE result = ary_new(klass, 1); VALUE *ptr = (VALUE *)ARY_EMBED_PTR(result); RB_OBJ_WRITE(result, ptr, values[offset]); ARY_SET_EMBED_LEN(result, 1); return result; } + else if (step < 0 && step < -len) { + step = -len; + } long ustep = (step < 0) ? -step : step; len = (len + ustep - 1) / ustep; diff --git a/enumerator.c b/enumerator.c index d7546ee9e82aa5..2c9858cda6d0f5 100644 --- a/enumerator.c +++ b/enumerator.c @@ -3802,6 +3802,13 @@ rb_arithmetic_sequence_beg_len_step(VALUE obj, long *begp, long *lenp, long *ste *stepp = step; if (step < 0) { + if (aseq.exclude_end && !NIL_P(aseq.end)) { + /* Handle exclusion before range reversal */ + aseq.end = LONG2NUM(NUM2LONG(aseq.end) + 1); + + /* Don't exclude the previous beginning */ + aseq.exclude_end = 0; + } VALUE tmp = aseq.begin; aseq.begin = aseq.end; aseq.end = tmp; diff --git a/ext/-test-/arith_seq/beg_len_step/beg_len_step.c b/ext/-test-/arith_seq/beg_len_step/beg_len_step.c new file mode 100644 index 00000000000000..40c8cbee82b9fa --- /dev/null +++ b/ext/-test-/arith_seq/beg_len_step/beg_len_step.c @@ -0,0 +1,19 @@ +#include "ruby/ruby.h" + +static VALUE +arith_seq_s_beg_len_step(VALUE mod, VALUE obj, VALUE len, VALUE err) +{ + VALUE r; + long beg, len2, step; + + r = rb_arithmetic_sequence_beg_len_step(obj, &beg, &len2, &step, NUM2LONG(len), NUM2INT(err)); + + return rb_ary_new_from_args(4, r, LONG2NUM(beg), LONG2NUM(len2), LONG2NUM(step)); +} + +void +Init_beg_len_step(void) +{ + VALUE cArithSeq = rb_path2class("Enumerator::ArithmeticSequence"); + rb_define_singleton_method(cArithSeq, "__beg_len_step__", arith_seq_s_beg_len_step, 3); +} diff --git a/ext/-test-/arith_seq/beg_len_step/depend b/ext/-test-/arith_seq/beg_len_step/depend new file mode 100644 index 00000000000000..36a2c4c71b1214 --- /dev/null +++ b/ext/-test-/arith_seq/beg_len_step/depend @@ -0,0 +1,161 @@ +# AUTOGENERATED DEPENDENCIES START +beg_len_step.o: $(RUBY_EXTCONF_H) +beg_len_step.o: $(arch_hdrdir)/ruby/config.h +beg_len_step.o: $(hdrdir)/ruby/assert.h +beg_len_step.o: $(hdrdir)/ruby/backward.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/assume.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/attributes.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/bool.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/inttypes.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/limits.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/long_long.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/stdalign.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/stdarg.h +beg_len_step.o: $(hdrdir)/ruby/defines.h +beg_len_step.o: $(hdrdir)/ruby/intern.h +beg_len_step.o: $(hdrdir)/ruby/internal/abi.h +beg_len_step.o: $(hdrdir)/ruby/internal/anyargs.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/char.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/double.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/int.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/long.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/short.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/assume.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/artificial.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/cold.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/const.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/constexpr.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/deprecated.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/error.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/forceinline.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/format.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/noalias.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/noexcept.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/noinline.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/nonnull.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/noreturn.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/pure.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/restrict.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/warning.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/weakref.h +beg_len_step.o: $(hdrdir)/ruby/internal/cast.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_since.h +beg_len_step.o: $(hdrdir)/ruby/internal/config.h +beg_len_step.o: $(hdrdir)/ruby/internal/constant_p.h +beg_len_step.o: $(hdrdir)/ruby/internal/core.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rarray.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rbasic.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rbignum.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rclass.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rdata.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rfile.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rhash.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/robject.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rregexp.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rstring.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rstruct.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +beg_len_step.o: $(hdrdir)/ruby/internal/ctype.h +beg_len_step.o: $(hdrdir)/ruby/internal/dllexport.h +beg_len_step.o: $(hdrdir)/ruby/internal/dosish.h +beg_len_step.o: $(hdrdir)/ruby/internal/error.h +beg_len_step.o: $(hdrdir)/ruby/internal/eval.h +beg_len_step.o: $(hdrdir)/ruby/internal/event.h +beg_len_step.o: $(hdrdir)/ruby/internal/fl_type.h +beg_len_step.o: $(hdrdir)/ruby/internal/gc.h +beg_len_step.o: $(hdrdir)/ruby/internal/glob.h +beg_len_step.o: $(hdrdir)/ruby/internal/globals.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/attribute.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/builtin.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/c_attribute.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/extension.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/feature.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/warning.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/array.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/bignum.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/class.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/compar.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/complex.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/cont.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/dir.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/enum.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/enumerator.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/error.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/eval.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/file.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/gc.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/hash.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/io.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/load.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/marshal.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/numeric.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/object.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/parse.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/proc.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/process.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/random.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/range.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/rational.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/re.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/ruby.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/select.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/signal.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/sprintf.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/string.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/struct.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/thread.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/time.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/variable.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/vm.h +beg_len_step.o: $(hdrdir)/ruby/internal/interpreter.h +beg_len_step.o: $(hdrdir)/ruby/internal/iterator.h +beg_len_step.o: $(hdrdir)/ruby/internal/memory.h +beg_len_step.o: $(hdrdir)/ruby/internal/method.h +beg_len_step.o: $(hdrdir)/ruby/internal/module.h +beg_len_step.o: $(hdrdir)/ruby/internal/newobj.h +beg_len_step.o: $(hdrdir)/ruby/internal/rgengc.h +beg_len_step.o: $(hdrdir)/ruby/internal/scan_args.h +beg_len_step.o: $(hdrdir)/ruby/internal/special_consts.h +beg_len_step.o: $(hdrdir)/ruby/internal/static_assert.h +beg_len_step.o: $(hdrdir)/ruby/internal/stdalign.h +beg_len_step.o: $(hdrdir)/ruby/internal/stdbool.h +beg_len_step.o: $(hdrdir)/ruby/internal/symbol.h +beg_len_step.o: $(hdrdir)/ruby/internal/value.h +beg_len_step.o: $(hdrdir)/ruby/internal/value_type.h +beg_len_step.o: $(hdrdir)/ruby/internal/variable.h +beg_len_step.o: $(hdrdir)/ruby/internal/warning_push.h +beg_len_step.o: $(hdrdir)/ruby/internal/xmalloc.h +beg_len_step.o: $(hdrdir)/ruby/missing.h +beg_len_step.o: $(hdrdir)/ruby/ruby.h +beg_len_step.o: $(hdrdir)/ruby/st.h +beg_len_step.o: $(hdrdir)/ruby/subst.h +beg_len_step.o: beg_len_step.c +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/arith_seq/beg_len_step/extconf.rb b/ext/-test-/arith_seq/beg_len_step/extconf.rb new file mode 100644 index 00000000000000..e72b3ad01f9c09 --- /dev/null +++ b/ext/-test-/arith_seq/beg_len_step/extconf.rb @@ -0,0 +1,2 @@ +# frozen_string_literal: false +create_makefile("-test-/arith_seq/beg_len_step") diff --git a/spec/ruby/core/array/shared/slice.rb b/spec/ruby/core/array/shared/slice.rb index 3b09fdcbc6fc2c..8fb33738b9ce6f 100644 --- a/spec/ruby/core/array/shared/slice.rb +++ b/spec/ruby/core/array/shared/slice.rb @@ -784,6 +784,102 @@ def to.to_int() -2 end a.send(@method, (...-9)).should == [] end + ruby_version_is "3.2" do + describe "can be sliced with Enumerator::ArithmeticSequence" do + it "with infinite/inverted ranges and negative steps" do + @array = [0, 1, 2, 3, 4, 5] + @array.send(@method, (2..).step(-1)).should == [2, 1, 0] + @array.send(@method, (2..).step(-2)).should == [2, 0] + @array.send(@method, (2..).step(-3)).should == [2] + @array.send(@method, (2..).step(-4)).should == [2] + + @array.send(@method, (-3..).step(-1)).should == [3, 2, 1, 0] + @array.send(@method, (-3..).step(-2)).should == [3, 1] + @array.send(@method, (-3..).step(-3)).should == [3, 0] + @array.send(@method, (-3..).step(-4)).should == [3] + @array.send(@method, (-3..).step(-5)).should == [3] + + @array.send(@method, (..0).step(-1)).should == [5, 4, 3, 2, 1, 0] + @array.send(@method, (..0).step(-2)).should == [5, 3, 1] + @array.send(@method, (..0).step(-3)).should == [5, 2] + @array.send(@method, (..0).step(-4)).should == [5, 1] + @array.send(@method, (..0).step(-5)).should == [5, 0] + @array.send(@method, (..0).step(-6)).should == [5] + @array.send(@method, (..0).step(-7)).should == [5] + + @array.send(@method, (...0).step(-1)).should == [5, 4, 3, 2, 1] + @array.send(@method, (...0).step(-2)).should == [5, 3, 1] + @array.send(@method, (...0).step(-3)).should == [5, 2] + @array.send(@method, (...0).step(-4)).should == [5, 1] + @array.send(@method, (...0).step(-5)).should == [5] + @array.send(@method, (...0).step(-6)).should == [5] + + @array.send(@method, (...1).step(-1)).should == [5, 4, 3, 2] + @array.send(@method, (...1).step(-2)).should == [5, 3] + @array.send(@method, (...1).step(-3)).should == [5, 2] + @array.send(@method, (...1).step(-4)).should == [5] + @array.send(@method, (...1).step(-5)).should == [5] + + @array.send(@method, (..-5).step(-1)).should == [5, 4, 3, 2, 1] + @array.send(@method, (..-5).step(-2)).should == [5, 3, 1] + @array.send(@method, (..-5).step(-3)).should == [5, 2] + @array.send(@method, (..-5).step(-4)).should == [5, 1] + @array.send(@method, (..-5).step(-5)).should == [5] + @array.send(@method, (..-5).step(-6)).should == [5] + + @array.send(@method, (...-5).step(-1)).should == [5, 4, 3, 2] + @array.send(@method, (...-5).step(-2)).should == [5, 3] + @array.send(@method, (...-5).step(-3)).should == [5, 2] + @array.send(@method, (...-5).step(-4)).should == [5] + @array.send(@method, (...-5).step(-5)).should == [5] + + @array.send(@method, (4..1).step(-1)).should == [4, 3, 2, 1] + @array.send(@method, (4..1).step(-2)).should == [4, 2] + @array.send(@method, (4..1).step(-3)).should == [4, 1] + @array.send(@method, (4..1).step(-4)).should == [4] + @array.send(@method, (4..1).step(-5)).should == [4] + + @array.send(@method, (4...1).step(-1)).should == [4, 3, 2] + @array.send(@method, (4...1).step(-2)).should == [4, 2] + @array.send(@method, (4...1).step(-3)).should == [4] + @array.send(@method, (4...1).step(-4)).should == [4] + + @array.send(@method, (-2..1).step(-1)).should == [4, 3, 2, 1] + @array.send(@method, (-2..1).step(-2)).should == [4, 2] + @array.send(@method, (-2..1).step(-3)).should == [4, 1] + @array.send(@method, (-2..1).step(-4)).should == [4] + @array.send(@method, (-2..1).step(-5)).should == [4] + + @array.send(@method, (-2...1).step(-1)).should == [4, 3, 2] + @array.send(@method, (-2...1).step(-2)).should == [4, 2] + @array.send(@method, (-2...1).step(-3)).should == [4] + @array.send(@method, (-2...1).step(-4)).should == [4] + + @array.send(@method, (4..-5).step(-1)).should == [4, 3, 2, 1] + @array.send(@method, (4..-5).step(-2)).should == [4, 2] + @array.send(@method, (4..-5).step(-3)).should == [4, 1] + @array.send(@method, (4..-5).step(-4)).should == [4] + @array.send(@method, (4..-5).step(-5)).should == [4] + + @array.send(@method, (4...-5).step(-1)).should == [4, 3, 2] + @array.send(@method, (4...-5).step(-2)).should == [4, 2] + @array.send(@method, (4...-5).step(-3)).should == [4] + @array.send(@method, (4...-5).step(-4)).should == [4] + + @array.send(@method, (-2..-5).step(-1)).should == [4, 3, 2, 1] + @array.send(@method, (-2..-5).step(-2)).should == [4, 2] + @array.send(@method, (-2..-5).step(-3)).should == [4, 1] + @array.send(@method, (-2..-5).step(-4)).should == [4] + @array.send(@method, (-2..-5).step(-5)).should == [4] + + @array.send(@method, (-2...-5).step(-1)).should == [4, 3, 2] + @array.send(@method, (-2...-5).step(-2)).should == [4, 2] + @array.send(@method, (-2...-5).step(-3)).should == [4] + @array.send(@method, (-2...-5).step(-4)).should == [4] + end + end + end + it "can accept nil...nil ranges" do a = [0, 1, 2, 3, 4, 5] a.send(@method, eval("(nil...nil)")).should == a diff --git a/test/-ext-/arith_seq/test_arith_seq_beg_len_step.rb b/test/-ext-/arith_seq/test_arith_seq_beg_len_step.rb new file mode 100644 index 00000000000000..4320c1f20dc233 --- /dev/null +++ b/test/-ext-/arith_seq/test_arith_seq_beg_len_step.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: false +require 'test/unit' + +class Test_ArithSeq < Test::Unit::TestCase + def test_beg_len_step + assert_separately([], <<-"end;") #do + require '-test-/arith_seq/beg_len_step' + + r, = Enumerator::ArithmeticSequence.__beg_len_step__([1, 2, 3], 0, 0) + assert_equal(false, r) + + r, = Enumerator::ArithmeticSequence.__beg_len_step__([1, 2, 3], 1, 0) + assert_equal(false, r) + + r, = Enumerator::ArithmeticSequence.__beg_len_step__([1, 2, 3], 3, 0) + assert_equal(false, r) + + r, = Enumerator::ArithmeticSequence.__beg_len_step__(1..3, 0, 0) + assert_equal(nil, r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__(1..3, 1, 0) + assert_equal([true, 1, 0, 1], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__(1..3, 2, 0) + assert_equal([true, 1, 1, 1], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__(1..3, 3, 0) + assert_equal([true, 1, 2, 1], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__(1..3, 4, 0) + assert_equal([true, 1, 3, 1], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__(1..3, 5, 0) + assert_equal([true, 1, 3, 1], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__((-10..10).step(2), 24, 0) + assert_equal([true, 14, 0, 2], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__((-10..10).step(3), 24, 0) + assert_equal([true, 14, 0, 3], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__((-10..10).step(3), 22, 0) + assert_equal([true, 12, 0, 3], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__((-10..10).step(-3), 22, 0) + assert_equal([true, 10, 3, -3], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__(1..3, 0, 1) + assert_equal([true, 1, 3, 1], r) + end; + end +end diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index e376d76a169d86..6ee468eaef29c7 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -1580,6 +1580,96 @@ def test_slice assert_equal_instance(a.values_at(*idx), a.slice((3..90)%2)) idx = 90.step(3, -2).to_a assert_equal_instance(a.values_at(*idx), a.slice((90 .. 3)% -2)) + + a = [0, 1, 2, 3, 4, 5] + assert_equal([2, 1, 0], a.slice((2..).step(-1))) + assert_equal([2, 0], a.slice((2..).step(-2))) + assert_equal([2], a.slice((2..).step(-3))) + assert_equal([2], a.slice((2..).step(-4))) + + assert_equal([3, 2, 1, 0], a.slice((-3..).step(-1))) + assert_equal([3, 1], a.slice((-3..).step(-2))) + assert_equal([3, 0], a.slice((-3..).step(-3))) + assert_equal([3], a.slice((-3..).step(-4))) + assert_equal([3], a.slice((-3..).step(-5))) + + assert_equal([5, 4, 3, 2, 1, 0], a.slice((..0).step(-1))) + assert_equal([5, 3, 1], a.slice((..0).step(-2))) + assert_equal([5, 2], a.slice((..0).step(-3))) + assert_equal([5, 1], a.slice((..0).step(-4))) + assert_equal([5, 0], a.slice((..0).step(-5))) + assert_equal([5], a.slice((..0).step(-6))) + assert_equal([5], a.slice((..0).step(-7))) + + assert_equal([5, 4, 3, 2, 1], a.slice((...0).step(-1))) + assert_equal([5, 3, 1], a.slice((...0).step(-2))) + assert_equal([5, 2], a.slice((...0).step(-3))) + assert_equal([5, 1], a.slice((...0).step(-4))) + assert_equal([5], a.slice((...0).step(-5))) + assert_equal([5], a.slice((...0).step(-6))) + + assert_equal([5, 4, 3, 2], a.slice((...1).step(-1))) + assert_equal([5, 3], a.slice((...1).step(-2))) + assert_equal([5, 2], a.slice((...1).step(-3))) + assert_equal([5], a.slice((...1).step(-4))) + assert_equal([5], a.slice((...1).step(-5))) + + assert_equal([5, 4, 3, 2, 1], a.slice((..-5).step(-1))) + assert_equal([5, 3, 1], a.slice((..-5).step(-2))) + assert_equal([5, 2], a.slice((..-5).step(-3))) + assert_equal([5, 1], a.slice((..-5).step(-4))) + assert_equal([5], a.slice((..-5).step(-5))) + assert_equal([5], a.slice((..-5).step(-6))) + + assert_equal([5, 4, 3, 2], a.slice((...-5).step(-1))) + assert_equal([5, 3], a.slice((...-5).step(-2))) + assert_equal([5, 2], a.slice((...-5).step(-3))) + assert_equal([5], a.slice((...-5).step(-4))) + assert_equal([5], a.slice((...-5).step(-5))) + + assert_equal([4, 3, 2, 1], a.slice((4..1).step(-1))) + assert_equal([4, 2], a.slice((4..1).step(-2))) + assert_equal([4, 1], a.slice((4..1).step(-3))) + assert_equal([4], a.slice((4..1).step(-4))) + assert_equal([4], a.slice((4..1).step(-5))) + + assert_equal([4, 3, 2], a.slice((4...1).step(-1))) + assert_equal([4, 2], a.slice((4...1).step(-2))) + assert_equal([4], a.slice((4...1).step(-3))) + assert_equal([4], a.slice((4...1).step(-4))) + + assert_equal([4, 3, 2, 1], a.slice((-2..1).step(-1))) + assert_equal([4, 2], a.slice((-2..1).step(-2))) + assert_equal([4, 1], a.slice((-2..1).step(-3))) + assert_equal([4], a.slice((-2..1).step(-4))) + assert_equal([4], a.slice((-2..1).step(-5))) + + assert_equal([4, 3, 2], a.slice((-2...1).step(-1))) + assert_equal([4, 2], a.slice((-2...1).step(-2))) + assert_equal([4], a.slice((-2...1).step(-3))) + assert_equal([4], a.slice((-2...1).step(-4))) + + assert_equal([4, 3, 2, 1], a.slice((4..-5).step(-1))) + assert_equal([4, 2], a.slice((4..-5).step(-2))) + assert_equal([4, 1], a.slice((4..-5).step(-3))) + assert_equal([4], a.slice((4..-5).step(-4))) + assert_equal([4], a.slice((4..-5).step(-5))) + + assert_equal([4, 3, 2], a.slice((4...-5).step(-1))) + assert_equal([4, 2], a.slice((4...-5).step(-2))) + assert_equal([4], a.slice((4...-5).step(-3))) + assert_equal([4], a.slice((4...-5).step(-4))) + + assert_equal([4, 3, 2, 1], a.slice((-2..-5).step(-1))) + assert_equal([4, 2], a.slice((-2..-5).step(-2))) + assert_equal([4, 1], a.slice((-2..-5).step(-3))) + assert_equal([4], a.slice((-2..-5).step(-4))) + assert_equal([4], a.slice((-2..-5).step(-5))) + + assert_equal([4, 3, 2], a.slice((-2...-5).step(-1))) + assert_equal([4, 2], a.slice((-2...-5).step(-2))) + assert_equal([4], a.slice((-2...-5).step(-3))) + assert_equal([4], a.slice((-2...-5).step(-4))) end def test_slice_out_of_range From c361cf44c03275405989022054d7c20efcc2a2ce Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Thu, 11 Aug 2022 08:51:04 -0500 Subject: [PATCH 09/12] [ruby/rdoc] [DOC] Make example formats explicit and consistent (https://github.com/ruby/rdoc/pull/913) https://github.com/ruby/rdoc/commit/7e6ef6c855 --- doc/rdoc/markup_reference.rb | 153 ++++++++++++++++++++--------------- 1 file changed, 87 insertions(+), 66 deletions(-) diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb index b3d1d97f4f61be..059511f478e009 100644 --- a/doc/rdoc/markup_reference.rb +++ b/doc/rdoc/markup_reference.rb @@ -29,16 +29,37 @@ # see :nodoc:, :doc:, and :notnew. # - \RDoc directives in single-line comments; # see other {Directives}[rdoc-ref:RDoc::MarkupReference@Directives]. -# - The Ruby code itself; -# see {Documentation Derived from Ruby Code}[rdoc-ref:RDoc::MarkupReference@Documentation+Derived+from+Ruby+Code] +# - The Ruby code itself (but not from C code); +# see {Documentation Derived from Ruby Code}[rdoc-ref:RDoc::MarkupReference@Documentation+Derived+from+Ruby+Code]. # # == Markup in Comments # -# A single-line or multi-line comment that immediately precedes -# the definition of a class, module, method, alias, constant, or attribute -# becomes the documentation for that defined object. +# The treatment of markup in comments varies according to the type of file: # -# (\RDoc ignores other such comments that do not precede definitions.) +# - .rb (Ruby code file): markup is parsed from Ruby comments. +# - .c (C code file): markup is parsed from C comments. +# - .rdoc (RDoc text file): markup is parsed from the entire file. +# +# The comment associated with +# a Ruby class, module, method, alias, constant, or attribute +# becomes the documentation for that defined object: +# +# - In a Ruby file, that comment immediately precedes +# the definition of the object. +# - In a C file, that comment immediately precedes +# the function that implements a method, +# or otherwise immediately precedes the definition of the object. +# +# In either a Ruby or a C file, +# \RDoc ignores comments that do not precede object definitions. +# +# In an \RDoc file, the text is not associated with any code object, +# but may (depending on how the documentation is built), +# become a separate page. +# +# Almost all examples on this page are all RDoc-like; +# that is, they have no comment markers like Ruby # +# or C /* ... */. # # === Margins # @@ -96,11 +117,11 @@ # # Example input: # -# # \RDoc produces HTML and command-line documentation for Ruby projects. -# # \RDoc includes the rdoc and ri tools for generating and displaying -# # documentation from the command-line. -# # -# # You'll love it. +# \RDoc produces HTML and command-line documentation for Ruby projects. +# \RDoc includes the rdoc and ri tools for generating and displaying +# documentation from the command-line. +# +# You'll love it. # # Rendered HTML: # >>> @@ -133,15 +154,15 @@ # # Example input: # -# # This is not verbatim text. -# # -# # This is verbatim text. -# # Whitespace is honored. # See? -# # Whitespace is honored. # See? -# # -# # This is still the same verbatim text block. -# # -# # This is not verbatim text. +# This is not verbatim text. +# +# This is verbatim text. +# Whitespace is honored. # See? +# Whitespace is honored. # See? +# +# This is still the same verbatim text block. +# +# This is not verbatim text. # # Rendered HTML: # >>> @@ -279,13 +300,13 @@ # # Example input: # -# # - An item. -# # - Another. -# # - An item spanning -# # multiple lines. -# # -# # * Yet another. -# # - Last one. +# - An item. +# - Another. +# - An item spanning +# multiple lines. +# +# * Yet another. +# - Last one. # # Rendered HTML: # >>> @@ -305,13 +326,13 @@ # # Example input: # -# # 100. An item. -# # 10. Another. -# # 1. An item spanning -# # multiple lines. -# # -# # 1. Yet another. -# # 1000. Last one. +# 100. An item. +# 10. Another. +# 1. An item spanning +# multiple lines. +# +# 1. Yet another. +# 1000. Last one. # # Rendered HTML: # >>> @@ -331,13 +352,13 @@ # # Example input: # -# # z. An item. -# # y. Another. -# # x. An item spanning -# # multiple lines. -# # -# # x. Yet another. -# # a. Last one. +# z. An item. +# y. Another. +# x. An item spanning +# multiple lines. +# +# x. Yet another. +# a. Last one. # # Rendered HTML: # >>> @@ -356,13 +377,13 @@ # # Example input: # -# # [foo] An item. -# # bat:: Another. -# # [bag] An item spanning -# # multiple lines. -# # -# # [bar baz] Yet another. -# # bam:: Last one. +# [foo] An item. +# bat:: Another. +# [bag] An item spanning +# multiple lines. +# +# [bar baz] Yet another. +# bam:: Last one. # # Rendered HTML: # >>> @@ -381,20 +402,20 @@ # # Examples: # -# # = Section 1 -# # == Section 1.1 -# # === Section 1.1.1 -# # === Section 1.1.2 -# # == Section 1.2 -# # = Section 2 -# # = Foo -# # == Bar -# # === Baz -# # ==== Bam -# # ===== Bat -# # ====== Bad -# # ============Still a Heading (Level 6) -# # \== Not a Heading +# = Section 1 +# == Section 1.1 +# === Section 1.1.1 +# === Section 1.1.2 +# == Section 1.2 +# = Section 2 +# = Foo +# == Bar +# === Baz +# ==== Bam +# ===== Bat +# ====== Bad +# ============Still a Heading (Level 6) +# \== Not a Heading # # A heading may contain only one type of nested block: # @@ -1147,10 +1168,10 @@ def dummy_instance_method(foo, bar); end; # # Here is the :call-seq: directive given for the method: # - # # :call-seq: - # # call_seq_directive(foo, bar) - # # Can be anything -> bar - # # Also anything more -> baz or bat + # :call-seq: + # call_seq_directive(foo, bar) + # Can be anything -> bar + # Also anything more -> baz or bat # def call_seq_directive nil From 49517b3bb436456407e0ee099c7442f3ab5ac53d Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Fri, 26 Feb 2021 12:14:48 -0800 Subject: [PATCH 10/12] Fix inspect for unicode codepoint 0x85 This is an inelegant hack, by manually checking for this specific code point in rb_str_inspect. Some testing indicates that this is the only code point affected. It's possible a better fix would be inside of lower-level encoding code, such that rb_enc_isprint would return false and not true for codepoint 0x85. Fixes [Bug #16842] --- string.c | 10 +++++++++- test/ruby/test_string.rb | 5 +++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/string.c b/string.c index 85819e26a393a3..e74783cf923652 100644 --- a/string.c +++ b/string.c @@ -6777,7 +6777,15 @@ rb_str_inspect(VALUE str) prev = p; continue; } - if ((enc == resenc && rb_enc_isprint(c, enc)) || + /* The special casing of 0x85 (NEXT_LINE) here is because + * Oniguruma historically treats it as printable, but it + * doesn't match the print POSIX bracket class or character + * property in regexps. + * + * See Ruby Bug #16842 for details: + * https://bugs.ruby-lang.org/issues/16842 + */ + if ((enc == resenc && rb_enc_isprint(c, enc) && c != 0x85) || (asciicompat && rb_enc_isascii(c, enc) && ISPRINT(c))) { continue; } diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb index d37924dec1904e..ab14a3c17bb7f2 100644 --- a/test/ruby/test_string.rb +++ b/test/ruby/test_string.rb @@ -2614,6 +2614,11 @@ def test_inspect_nul assert_equal '"\x0012"', s.inspect, bug8290 end + def test_inspect_next_line + bug16842 = '[ruby-core:98231]' + assert_equal '"\\u0085"', 0x85.chr(Encoding::UTF_8).inspect, bug16842 + end + def test_partition assert_equal(%w(he l lo), S("hello").partition(/l/)) assert_equal(%w(he l lo), S("hello").partition("l")) From a677aa0fcf6b43668b1e6ceac67b4a4121afd818 Mon Sep 17 00:00:00 2001 From: git Date: Fri, 12 Aug 2022 00:47:48 +0900 Subject: [PATCH 11/12] * 2022-08-12 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index 780a93e8dcc0de..1b561623e94b58 100644 --- a/version.h +++ b/version.h @@ -15,7 +15,7 @@ #define RUBY_RELEASE_YEAR 2022 #define RUBY_RELEASE_MONTH 8 -#define RUBY_RELEASE_DAY 11 +#define RUBY_RELEASE_DAY 12 #include "ruby/version.h" #include "ruby/internal/abi.h" From 8a3f401b24e1b5f3e3a0f44c568a3e66ed595d42 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Thu, 11 Aug 2022 11:43:39 -0500 Subject: [PATCH 12/12] [ruby/rdoc] Improvements to Text Markup examples (https://github.com/ruby/rdoc/pull/915) https://github.com/ruby/rdoc/commit/d00ddfe57c --- doc/rdoc/markup_reference.rb | 104 ++++++++++++++++------------------- 1 file changed, 48 insertions(+), 56 deletions(-) diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb index 059511f478e009..c7578f3581107f 100644 --- a/doc/rdoc/markup_reference.rb +++ b/doc/rdoc/markup_reference.rb @@ -649,27 +649,27 @@ # # Example input: # -# Two words in a paragraph. +# Italicized words in a paragraph. # # >>> -# Two words in a block quote. +# Italicized words in a block quote. # -# - Two words in a bullet list item. +# - Italicized words in a list item. # -# ====== Two words in a Heading +# ====== Italicized words in a Heading # # Italicized passage containing *bold* and +monofont+. # # Rendered HTML: # >>> -# Two words in a paragraph. +# Italicized words in a paragraph. # # >>> -# Two words in a block quote. +# Italicized words in a block quote. # -# - Two words in a bullet list item. +# - Italicized words in a list item. # -# ====== Two words in a Heading +# ====== Italicized words in a Heading # # Italicized passage containing *bold* and +monofont+. # @@ -678,29 +678,25 @@ # # Example input: # -# _Word_ in a paragraph. +# _Italic_ in a paragraph. # # >>> -# _Word_ in a block quote. +# _Italic_ in a block quote. # -# - _Word_ in a bullet list item. +# - _Italic_ in a list item. # -# [_word_] _Word_ in a labeled list item. -# -# ====== _Word_ in a Heading +# ====== _Italic_ in a Heading # # Rendered HTML: # >>> -# _Word_ in a paragraph. +# _Italic_ in a paragraph. # # >>> -# _Word_ in a block quote. -# -# - _Word_ in a bullet list item. +# _Italic_ in a block quote. # -# [_word_] _Word_ in a labeled list item. +# - _Italic_ in a list item. # -# ====== _Word_ in a Heading +# ====== _Italic_ in a Heading # # ===== Bold # @@ -708,28 +704,28 @@ # # Example input: # -# Two words in a paragraph. +# Bold words in a paragraph. # # >>> -# Two words in a block quote. +# Bold words in a block quote. # -# - Two words in a bullet list item. +# - Bold words in a list item. # -# ====== Two words in a Heading +# ====== Bold words in a Heading # # Bold passage containing _italics_ and +monofont+. # # Rendered HTML: # # >>> -# Two words in a paragraph. +# Bold words in a paragraph. # # >>> -# Two words in a block quote. +# Bold words in a block quote. # -# - Two words in a bullet list item. +# - Bold words in a list item. # -# ====== Two words in a Heading +# ====== Bold words in a Heading # # Bold passage containing _italics_ and +monofont+. # @@ -738,30 +734,26 @@ # # Example input: # -# *Word* in a paragraph. +# *Bold* in a paragraph. # # >>> -# *Word* in a block quote. +# *Bold* in a block quote. # -# - *Word* in a bullet list item. +# - *Bold* in a list item. # -# [*word*] *Word* in a labeled list item. -# -# ===== *Word* in a Heading +# ===== *Bold* in a Heading # # Rendered HTML: # # >>> -# *Word* in a paragraph. +# *Bold* in a paragraph. # # >>> -# *Word* in a block quote. -# -# - *Word* in a bullet list item. +# *Bold* in a block quote. # -# [*word*] *Word* in a labeled list item. +# - *Bold* in a list item. # -# ===== *Word* in a Heading +# ===== *Bold* in a Heading # # ===== Monofont # @@ -771,28 +763,28 @@ # # Example input: # -# Two words in a paragraph. +# Monofont words in a paragraph. # # >>> -# Two words in a block quote. +# Monofont words in a block quote. # -# - Two words in a bullet list item. +# - Monofont words in a list item. # -# ====== Two words in heading +# ====== Monofont words in heading # # Monofont passage containing _italics_ and *bold*. # # Rendered HTML: # # >>> -# Two words in a paragraph. +# Monofont words in a paragraph. # # >>> -# Two words in a block quote. +# Monofont words in a block quote. # -# - Two words in a bullet list item. +# - Monofont words in a list item. # -# ====== Two words in heading +# ====== Monofont words in heading # # Monofont passage containing _italics_ and *bold*. # @@ -801,26 +793,26 @@ # # Example input: # -# +Word+ in a paragraph. +# +Monofont+ in a paragraph. # # >>> -# +Word+ in a block quote. +# +Monofont+ in a block quote. # -# - +Word+ in a bullet list item. +# - +Monofont+ in a list item. # -# ====== +Word+ in a Heading +# ====== +Monofont+ in a Heading # # Rendered HTML: # # >>> -# +Word+ in a paragraph. +# +Monofont+ in a paragraph. # # >>> -# +Word+ in a block quote. +# +Monofont+ in a block quote. # -# - +Word+ in a bullet list item. +# - +Monofont+ in a list item. # -# ====== +Word+ in a Heading +# ====== +Monofont+ in a Heading # # ==== Escaping Text Markup #