Merge strscan-3.0.5
This commit is contained in:
parent
bcf01b18cf
commit
4e31fea77d
Notes:
git
2022-12-09 07:36:48 +00:00
@ -1,5 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
require 'mkmf'
|
require 'mkmf'
|
||||||
$INCFLAGS << " -I$(top_srcdir)" if $extmk
|
if RUBY_ENGINE == 'ruby'
|
||||||
have_func("onig_region_memsize", "ruby.h")
|
$INCFLAGS << " -I$(top_srcdir)" if $extmk
|
||||||
create_makefile 'strscan'
|
have_func("onig_region_memsize", "ruby.h")
|
||||||
|
create_makefile 'strscan'
|
||||||
|
else
|
||||||
|
File.write('Makefile', dummy_makefile("").join)
|
||||||
|
end
|
||||||
|
@ -22,7 +22,7 @@ extern size_t onig_region_memsize(const struct re_registers *regs);
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define STRSCAN_VERSION "3.0.1"
|
#define STRSCAN_VERSION "3.0.5"
|
||||||
|
|
||||||
/* =======================================================================
|
/* =======================================================================
|
||||||
Data Type Definitions
|
Data Type Definitions
|
||||||
@ -435,11 +435,11 @@ strscan_get_pos(VALUE self)
|
|||||||
*
|
*
|
||||||
* In short, it's a 0-based index into the string.
|
* In short, it's a 0-based index into the string.
|
||||||
*
|
*
|
||||||
* s = StringScanner.new("abcädeföghi")
|
* s = StringScanner.new("abc\u00e4def\u00f6ghi")
|
||||||
* s.charpos # -> 0
|
* s.charpos # -> 0
|
||||||
* s.scan_until(/ä/) # -> "abcä"
|
* s.scan_until(/\u00e4/) # -> "abc\u00E4"
|
||||||
* s.pos # -> 5
|
* s.pos # -> 5
|
||||||
* s.charpos # -> 4
|
* s.charpos # -> 4
|
||||||
*/
|
*/
|
||||||
static VALUE
|
static VALUE
|
||||||
strscan_get_charpos(VALUE self)
|
strscan_get_charpos(VALUE self)
|
||||||
@ -1458,6 +1458,54 @@ strscan_fixed_anchor_p(VALUE self)
|
|||||||
return p->fixed_anchor_p ? Qtrue : Qfalse;
|
return p->fixed_anchor_p ? Qtrue : Qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
VALUE self;
|
||||||
|
VALUE captures;
|
||||||
|
} named_captures_data;
|
||||||
|
|
||||||
|
static int
|
||||||
|
named_captures_iter(const OnigUChar *name,
|
||||||
|
const OnigUChar *name_end,
|
||||||
|
int back_num,
|
||||||
|
int *back_refs,
|
||||||
|
OnigRegex regex,
|
||||||
|
void *arg)
|
||||||
|
{
|
||||||
|
named_captures_data *data = arg;
|
||||||
|
|
||||||
|
VALUE key = rb_str_new((const char *)name, name_end - name);
|
||||||
|
VALUE value = RUBY_Qnil;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < back_num; i++) {
|
||||||
|
value = strscan_aref(data->self, INT2NUM(back_refs[i]));
|
||||||
|
}
|
||||||
|
rb_hash_aset(data->captures, key, value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* scanner.named_captures -> hash
|
||||||
|
*
|
||||||
|
* Returns a hash of string variables matching the regular expression.
|
||||||
|
*
|
||||||
|
* scan = StringScanner.new('foobarbaz')
|
||||||
|
* scan.match?(/(?<f>foo)(?<r>bar)(?<z>baz)/)
|
||||||
|
* scan.named_captures # -> {"f"=>"foo", "r"=>"bar", "z"=>"baz"}
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
strscan_named_captures(VALUE self)
|
||||||
|
{
|
||||||
|
struct strscanner *p;
|
||||||
|
GET_SCANNER(self, p);
|
||||||
|
named_captures_data data;
|
||||||
|
data.self = self;
|
||||||
|
data.captures = rb_hash_new();
|
||||||
|
onig_foreach_name(RREGEXP_PTR(p->regex), named_captures_iter, &data);
|
||||||
|
|
||||||
|
return data.captures;
|
||||||
|
}
|
||||||
|
|
||||||
/* =======================================================================
|
/* =======================================================================
|
||||||
Ruby Interface
|
Ruby Interface
|
||||||
======================================================================= */
|
======================================================================= */
|
||||||
@ -1468,6 +1516,8 @@ strscan_fixed_anchor_p(VALUE self)
|
|||||||
* StringScanner provides for lexical scanning operations on a String. Here is
|
* StringScanner provides for lexical scanning operations on a String. Here is
|
||||||
* an example of its usage:
|
* an example of its usage:
|
||||||
*
|
*
|
||||||
|
* require 'strscan'
|
||||||
|
*
|
||||||
* s = StringScanner.new('This is an example string')
|
* s = StringScanner.new('This is an example string')
|
||||||
* s.eos? # -> false
|
* s.eos? # -> false
|
||||||
*
|
*
|
||||||
@ -1650,4 +1700,6 @@ Init_strscan(void)
|
|||||||
rb_define_method(StringScanner, "inspect", strscan_inspect, 0);
|
rb_define_method(StringScanner, "inspect", strscan_inspect, 0);
|
||||||
|
|
||||||
rb_define_method(StringScanner, "fixed_anchor?", strscan_fixed_anchor_p, 0);
|
rb_define_method(StringScanner, "fixed_anchor?", strscan_fixed_anchor_p, 0);
|
||||||
|
|
||||||
|
rb_define_method(StringScanner, "named_captures", strscan_named_captures, 0);
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,26 @@ Gem::Specification.new do |s|
|
|||||||
s.summary = "Provides lexical scanning operations on a String."
|
s.summary = "Provides lexical scanning operations on a String."
|
||||||
s.description = "Provides lexical scanning operations on a String."
|
s.description = "Provides lexical scanning operations on a String."
|
||||||
|
|
||||||
s.require_path = %w{lib}
|
files = [
|
||||||
s.files = %w{ext/strscan/extconf.rb ext/strscan/strscan.c}
|
"COPYING",
|
||||||
s.extensions = %w{ext/strscan/extconf.rb}
|
"LICENSE.txt",
|
||||||
|
]
|
||||||
|
if RUBY_ENGINE == "jruby"
|
||||||
|
s.require_paths = %w{ext/jruby/lib lib}
|
||||||
|
files << "ext/jruby/lib/strscan.rb"
|
||||||
|
files << "lib/strscan.jar"
|
||||||
|
s.platform = "java"
|
||||||
|
else
|
||||||
|
s.require_paths = %w{lib}
|
||||||
|
files << "ext/strscan/extconf.rb"
|
||||||
|
files << "ext/strscan/strscan.c"
|
||||||
|
s.extensions = %w{ext/strscan/extconf.rb}
|
||||||
|
end
|
||||||
|
s.files = files
|
||||||
s.required_ruby_version = ">= 2.4.0"
|
s.required_ruby_version = ">= 2.4.0"
|
||||||
|
|
||||||
s.authors = ["Minero Aoki", "Sutou Kouhei"]
|
s.authors = ["Minero Aoki", "Sutou Kouhei", "Charles Oliver Nutter"]
|
||||||
s.email = [nil, "kou@cozmixng.org"]
|
s.email = [nil, "kou@cozmixng.org", "headius@headius.com"]
|
||||||
s.homepage = "https://github.com/ruby/strscan"
|
s.homepage = "https://github.com/ruby/strscan"
|
||||||
s.licenses = ["Ruby", "BSD-2-Clause"]
|
s.licenses = ["Ruby", "BSD-2-Clause"]
|
||||||
end
|
end
|
||||||
|
@ -3,7 +3,7 @@ require 'test/unit'
|
|||||||
|
|
||||||
class TestStringScannerRactor < Test::Unit::TestCase
|
class TestStringScannerRactor < Test::Unit::TestCase
|
||||||
def setup
|
def setup
|
||||||
pend unless defined? Ractor
|
omit "Ractor not defined" unless defined? Ractor
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_ractor
|
def test_ractor
|
||||||
|
@ -207,6 +207,8 @@ class TestStringScanner < Test::Unit::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_charpos_not_use_string_methods
|
def test_charpos_not_use_string_methods
|
||||||
|
omit "not supported on TruffleRuby" if RUBY_ENGINE == "truffleruby"
|
||||||
|
|
||||||
string = +'abcädeföghi'
|
string = +'abcädeföghi'
|
||||||
scanner = create_string_scanner(string)
|
scanner = create_string_scanner(string)
|
||||||
|
|
||||||
@ -567,6 +569,8 @@ class TestStringScanner < Test::Unit::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_invalid_encoding_string
|
def test_invalid_encoding_string
|
||||||
|
omit "no encoding check on TruffleRuby for scan(String)" if RUBY_ENGINE == "truffleruby"
|
||||||
|
|
||||||
str = "\xA1\xA2".dup.force_encoding("euc-jp")
|
str = "\xA1\xA2".dup.force_encoding("euc-jp")
|
||||||
ss = create_string_scanner(str)
|
ss = create_string_scanner(str)
|
||||||
assert_raise(Encoding::CompatibilityError) do
|
assert_raise(Encoding::CompatibilityError) do
|
||||||
@ -712,6 +716,8 @@ class TestStringScanner < Test::Unit::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_aref_without_regex
|
def test_aref_without_regex
|
||||||
|
omit "#[:missing] always raises on TruffleRuby if matched" if RUBY_ENGINE == "truffleruby"
|
||||||
|
|
||||||
s = create_string_scanner('abc')
|
s = create_string_scanner('abc')
|
||||||
s.get_byte
|
s.get_byte
|
||||||
assert_nil(s[:c])
|
assert_nil(s[:c])
|
||||||
@ -757,6 +763,33 @@ class TestStringScanner < Test::Unit::TestCase
|
|||||||
assert_equal(false, StringScanner.new("a", fixed_anchor: nil).fixed_anchor?)
|
assert_equal(false, StringScanner.new("a", fixed_anchor: nil).fixed_anchor?)
|
||||||
assert_equal(false, StringScanner.new("a", fixed_anchor: false).fixed_anchor?)
|
assert_equal(false, StringScanner.new("a", fixed_anchor: false).fixed_anchor?)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_scan_aref_repeatedly
|
||||||
|
s = StringScanner.new('test string')
|
||||||
|
assert_equal "test", s.scan(/\w(\w)(\w*)/)
|
||||||
|
assert_equal "test", s[0]
|
||||||
|
assert_equal "e", s[1]
|
||||||
|
assert_equal "st", s[2]
|
||||||
|
assert_nil s.scan(/\w+/)
|
||||||
|
assert_nil s[0]
|
||||||
|
assert_nil s[1]
|
||||||
|
assert_nil s[2]
|
||||||
|
assert_equal " ", s.scan(/\s+/)
|
||||||
|
assert_equal " ", s[0]
|
||||||
|
assert_nil s[1]
|
||||||
|
assert_nil s[2]
|
||||||
|
assert_equal "string", s.scan(/\w(\w)(\w*)/)
|
||||||
|
assert_equal "string", s[0]
|
||||||
|
assert_equal "t", s[1]
|
||||||
|
assert_equal "ring", s[2]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_named_captures
|
||||||
|
omit("not implemented on TruffleRuby") if ["truffleruby"].include?(RUBY_ENGINE)
|
||||||
|
scan = StringScanner.new("foobarbaz")
|
||||||
|
assert_equal(9, scan.match?(/(?<f>foo)(?<r>bar)(?<z>baz)/))
|
||||||
|
assert_equal({"f" => "foo", "r" => "bar", "z" => "baz"}, scan.named_captures)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class TestStringScannerFixedAnchor < TestStringScanner
|
class TestStringScannerFixedAnchor < TestStringScanner
|
||||||
|
Loading…
x
Reference in New Issue
Block a user