strscan 3.1.7 → 3.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/doc/strscan/link_refs.txt +1 -1
- data/doc/strscan/methods/skip_until.md +4 -2
- data/doc/strscan/strscan.md +1 -1
- data/ext/strscan/extconf.rb +2 -0
- data/ext/strscan/strscan.c +49 -14
- data/lib/strscan/truffleruby.rb +423 -0
- data/lib/strscan.rb +20 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 144c87f4e5774d19bf10d74cdac87182c3c74d61d8bcee8abf8e4f499a151000
|
|
4
|
+
data.tar.gz: 735cd2043e82b4174dffed842d1d81c530fb3c782ae416d8c4985a40fdaa6f1c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d99add3c119e1bfdb95f2a6c4dd3a1b3d1f321de66d0a3bd7a40e437d8520b81ec0da2c37ac74c4acd5d16af921fcf773a7e708a36a368a311aa25f59cccbd92
|
|
7
|
+
data.tar.gz: 6aef751e0fe071d1c9eaca9ca5be1569c5ce7f296e31ad4a70f834fc82ea931f536ba097692aab6c76d722573a82dee06574076f79237067de284e26411611c5
|
data/doc/strscan/link_refs.txt
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[1]: rdoc-ref:StringScanner@Stored+String
|
|
2
|
-
[2]: rdoc-ref:StringScanner@Byte+Position
|
|
2
|
+
[2]: rdoc-ref:StringScanner@Byte+Position+Position
|
|
3
3
|
[3]: rdoc-ref:StringScanner@Target+Substring
|
|
4
4
|
[4]: rdoc-ref:StringScanner@Setting+the+Target+Substring
|
|
5
5
|
[5]: rdoc-ref:StringScanner@Traversing+the+Target+Substring
|
|
@@ -2,12 +2,13 @@ call-seq:
|
|
|
2
2
|
skip_until(pattern) -> matched_substring_size or nil
|
|
3
3
|
|
|
4
4
|
Attempts to [match][17] the given `pattern`
|
|
5
|
-
anywhere (at any [position][2]) in the [target substring][3]
|
|
6
|
-
does not modify the positions.
|
|
5
|
+
anywhere (at any [position][2]) in the [target substring][3].
|
|
7
6
|
|
|
8
7
|
If the match attempt succeeds:
|
|
9
8
|
|
|
10
9
|
- Sets [match values][9].
|
|
10
|
+
- Sets the [byte position][2] to the end of the matched substring;
|
|
11
|
+
may adjust the [character position][7].
|
|
11
12
|
- Returns the size of the matched substring.
|
|
12
13
|
|
|
13
14
|
```rb
|
|
@@ -42,6 +43,7 @@ If the match attempt fails:
|
|
|
42
43
|
|
|
43
44
|
- Clears match values.
|
|
44
45
|
- Returns `nil`.
|
|
46
|
+
- Does not update positions.
|
|
45
47
|
|
|
46
48
|
```rb
|
|
47
49
|
scanner.skip_until(/nope/) # => nil
|
data/doc/strscan/strscan.md
CHANGED
|
@@ -37,7 +37,7 @@ Some examples here assume that certain helper methods are defined:
|
|
|
37
37
|
- `match_values_cleared?(scanner)`:
|
|
38
38
|
Returns whether the scanner's [match values][9] are cleared.
|
|
39
39
|
|
|
40
|
-
See examples at [helper methods](helper_methods.md).
|
|
40
|
+
See examples at [helper methods](doc/strscan/helper_methods.md).
|
|
41
41
|
|
|
42
42
|
## The `StringScanner` \Object
|
|
43
43
|
|
data/ext/strscan/extconf.rb
CHANGED
|
@@ -5,6 +5,8 @@ if RUBY_ENGINE == 'ruby'
|
|
|
5
5
|
have_func("onig_region_memsize(NULL)")
|
|
6
6
|
have_func("rb_reg_onig_match", "ruby/re.h")
|
|
7
7
|
have_func("rb_deprecate_constant")
|
|
8
|
+
have_func("rb_gc_location", "ruby.h") # RUBY_VERSION >= 2.7
|
|
9
|
+
have_const("RUBY_TYPED_EMBEDDABLE", "ruby.h") # RUBY_VERSION >= 3.3
|
|
8
10
|
create_makefile 'strscan'
|
|
9
11
|
else
|
|
10
12
|
File.write('Makefile', dummy_makefile("").join)
|
data/ext/strscan/strscan.c
CHANGED
|
@@ -22,7 +22,7 @@ extern size_t onig_region_memsize(const struct re_registers *regs);
|
|
|
22
22
|
|
|
23
23
|
#include <stdbool.h>
|
|
24
24
|
|
|
25
|
-
#define STRSCAN_VERSION "3.1.
|
|
25
|
+
#define STRSCAN_VERSION "3.1.8"
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
#ifdef HAVE_RB_DEPRECATE_CONSTANT
|
|
@@ -182,12 +182,35 @@ extract_beg_len(struct strscanner *p, long beg_i, long len)
|
|
|
182
182
|
Constructor
|
|
183
183
|
======================================================================= */
|
|
184
184
|
|
|
185
|
+
#ifdef RUBY_TYPED_EMBEDDABLE
|
|
186
|
+
# define HAVE_RUBY_TYPED_EMBEDDABLE 1
|
|
187
|
+
#else
|
|
188
|
+
# ifdef HAVE_CONST_RUBY_TYPED_EMBEDDABLE
|
|
189
|
+
# define RUBY_TYPED_EMBEDDABLE RUBY_TYPED_EMBEDDABLE
|
|
190
|
+
# define HAVE_RUBY_TYPED_EMBEDDABLE 1
|
|
191
|
+
# else
|
|
192
|
+
# define RUBY_TYPED_EMBEDDABLE 0
|
|
193
|
+
# endif
|
|
194
|
+
#endif
|
|
195
|
+
|
|
196
|
+
#ifdef HAVE_RB_GC_LOCATION
|
|
197
|
+
static void
|
|
198
|
+
strscan_compact(void *ptr)
|
|
199
|
+
{
|
|
200
|
+
struct strscanner *p = ptr;
|
|
201
|
+
p->str = rb_gc_location(p->str);
|
|
202
|
+
p->regex = rb_gc_location(p->regex);
|
|
203
|
+
}
|
|
204
|
+
#else
|
|
205
|
+
#define rb_gc_mark_movable rb_gc_mark
|
|
206
|
+
#endif
|
|
207
|
+
|
|
185
208
|
static void
|
|
186
209
|
strscan_mark(void *ptr)
|
|
187
210
|
{
|
|
188
211
|
struct strscanner *p = ptr;
|
|
189
|
-
|
|
190
|
-
|
|
212
|
+
rb_gc_mark_movable(p->str);
|
|
213
|
+
rb_gc_mark_movable(p->regex);
|
|
191
214
|
}
|
|
192
215
|
|
|
193
216
|
static void
|
|
@@ -195,24 +218,37 @@ strscan_free(void *ptr)
|
|
|
195
218
|
{
|
|
196
219
|
struct strscanner *p = ptr;
|
|
197
220
|
onig_region_free(&(p->regs), 0);
|
|
221
|
+
#ifndef HAVE_RUBY_TYPED_EMBEDDABLE
|
|
198
222
|
ruby_xfree(p);
|
|
223
|
+
#endif
|
|
199
224
|
}
|
|
200
225
|
|
|
201
226
|
static size_t
|
|
202
227
|
strscan_memsize(const void *ptr)
|
|
203
228
|
{
|
|
204
|
-
|
|
205
|
-
|
|
229
|
+
size_t size = 0;
|
|
230
|
+
#ifndef HAVE_RUBY_TYPED_EMBEDDABLE
|
|
231
|
+
size += sizeof(struct strscanner);
|
|
232
|
+
#endif
|
|
233
|
+
|
|
206
234
|
#ifdef HAVE_ONIG_REGION_MEMSIZE
|
|
207
|
-
|
|
235
|
+
const struct strscanner *p = ptr;
|
|
236
|
+
size += onig_region_memsize(&p->regs) - sizeof(p->regs);
|
|
208
237
|
#endif
|
|
209
238
|
return size;
|
|
210
239
|
}
|
|
211
240
|
|
|
212
241
|
static const rb_data_type_t strscanner_type = {
|
|
213
|
-
"StringScanner",
|
|
214
|
-
|
|
215
|
-
|
|
242
|
+
.wrap_struct_name = "StringScanner",
|
|
243
|
+
.function = {
|
|
244
|
+
.dmark = strscan_mark,
|
|
245
|
+
.dfree = strscan_free,
|
|
246
|
+
.dsize = strscan_memsize,
|
|
247
|
+
#ifdef HAVE_RB_GC_LOCATION
|
|
248
|
+
.dcompact = strscan_compact,
|
|
249
|
+
#endif
|
|
250
|
+
},
|
|
251
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
|
|
216
252
|
};
|
|
217
253
|
|
|
218
254
|
static VALUE
|
|
@@ -1261,16 +1297,17 @@ strscan_parse_integer(struct strscanner *p, int base, long len)
|
|
|
1261
1297
|
}
|
|
1262
1298
|
|
|
1263
1299
|
static inline bool
|
|
1264
|
-
strscan_ascii_compat_fastpath(VALUE str)
|
|
1300
|
+
strscan_ascii_compat_fastpath(VALUE str)
|
|
1301
|
+
{
|
|
1265
1302
|
int encindex = ENCODING_GET_INLINED(str);
|
|
1266
|
-
|
|
1303
|
+
/* The overwhelming majority of strings are in one of these 3 encodings. */
|
|
1267
1304
|
return encindex == utf8_encindex || encindex == binary_encindex || encindex == usascii_encindex;
|
|
1268
1305
|
}
|
|
1269
1306
|
|
|
1270
1307
|
static inline void
|
|
1271
1308
|
strscan_must_ascii_compat(VALUE str)
|
|
1272
1309
|
{
|
|
1273
|
-
|
|
1310
|
+
/* The overwhelming majority of strings are in one of these 3 encodings. */
|
|
1274
1311
|
if (RB_LIKELY(strscan_ascii_compat_fastpath(str))) {
|
|
1275
1312
|
return;
|
|
1276
1313
|
}
|
|
@@ -2299,6 +2336,4 @@ Init_strscan(void)
|
|
|
2299
2336
|
rb_define_method(StringScanner, "fixed_anchor?", strscan_fixed_anchor_p, 0);
|
|
2300
2337
|
|
|
2301
2338
|
rb_define_method(StringScanner, "named_captures", strscan_named_captures, 0);
|
|
2302
|
-
|
|
2303
|
-
rb_require("strscan/strscan");
|
|
2304
2339
|
}
|
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# truffleruby_primitives: true
|
|
3
|
+
|
|
4
|
+
class StringScanner
|
|
5
|
+
class Error < StandardError
|
|
6
|
+
end
|
|
7
|
+
# :stopdoc:
|
|
8
|
+
unless ::Object.const_defined?(:ScanError)
|
|
9
|
+
::Object::ScanError = Error
|
|
10
|
+
::Object.deprecate_constant :ScanError
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
Version = '3.1.8'
|
|
14
|
+
Id = '$Id$'
|
|
15
|
+
|
|
16
|
+
def self.must_C_version = self
|
|
17
|
+
# :startdoc:
|
|
18
|
+
|
|
19
|
+
attr_reader :string, :pos
|
|
20
|
+
alias_method :pointer, :pos
|
|
21
|
+
|
|
22
|
+
def initialize(string, options = nil, fixed_anchor: false)
|
|
23
|
+
@string = Primitive.convert_with_to_str(string)
|
|
24
|
+
@fixed_anchor = Primitive.as_boolean(fixed_anchor)
|
|
25
|
+
@pos = 0
|
|
26
|
+
@last_match = nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def inspect
|
|
30
|
+
return "#<#{Primitive.class(self)} (uninitialized)>" unless @string
|
|
31
|
+
return "#<#{Primitive.class(self)} fin>" if eos?
|
|
32
|
+
|
|
33
|
+
before =
|
|
34
|
+
if @pos == 0
|
|
35
|
+
''
|
|
36
|
+
elsif @pos < 5
|
|
37
|
+
"#{@string.byteslice(0, @pos).inspect} "
|
|
38
|
+
else
|
|
39
|
+
"#{('...' + @string.byteslice(@pos - 5, 5)).inspect} "
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
after =
|
|
43
|
+
if @pos >= @string.bytesize - 5
|
|
44
|
+
" #{@string.byteslice(@pos..).inspect}"
|
|
45
|
+
else
|
|
46
|
+
" #{(@string.byteslice(@pos, 5) + '...').inspect}"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
"#<#{Primitive.class(self)} #{@pos}/#{@string.bytesize} #{before}@#{after}>"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def pos=(new_pos)
|
|
53
|
+
if new_pos < 0
|
|
54
|
+
new_pos += @string.bytesize
|
|
55
|
+
end
|
|
56
|
+
raise RangeError, 'index out of range' if new_pos < 0
|
|
57
|
+
raise RangeError, 'index out of range' if new_pos > @string.bytesize
|
|
58
|
+
@pos = new_pos
|
|
59
|
+
end
|
|
60
|
+
alias_method :pointer=, :pos=
|
|
61
|
+
|
|
62
|
+
def charpos = Primitive.string_byte_index_to_character_index(@string, @pos)
|
|
63
|
+
|
|
64
|
+
def rest = @string.byteslice(@pos, @string.bytesize)
|
|
65
|
+
|
|
66
|
+
def rest_size = @string.bytesize - @pos
|
|
67
|
+
|
|
68
|
+
def concat(more_string)
|
|
69
|
+
@string.concat(Primitive.convert_with_to_str(more_string))
|
|
70
|
+
self
|
|
71
|
+
end
|
|
72
|
+
alias_method :<<, :concat
|
|
73
|
+
|
|
74
|
+
def string=(other_string)
|
|
75
|
+
@string = Primitive.convert_with_to_str(other_string)
|
|
76
|
+
@pos = 0
|
|
77
|
+
@last_match = nil
|
|
78
|
+
other_string
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def reset
|
|
82
|
+
@pos = 0
|
|
83
|
+
@last_match = nil
|
|
84
|
+
self
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def terminate
|
|
88
|
+
@pos = @string.bytesize
|
|
89
|
+
@last_match = nil
|
|
90
|
+
self
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def unscan
|
|
94
|
+
if @last_match
|
|
95
|
+
@pos = Primitive.match_data_byte_begin(@last_match, 0)
|
|
96
|
+
@last_match = nil
|
|
97
|
+
self
|
|
98
|
+
else
|
|
99
|
+
raise Error, 'unscan failed: previous match record not exist'
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Predicates
|
|
104
|
+
|
|
105
|
+
def fixed_anchor? = @fixed_anchor
|
|
106
|
+
|
|
107
|
+
def beginning_of_line?
|
|
108
|
+
@pos == 0 or @string.byteslice(@pos-1, 1) == "\n"
|
|
109
|
+
end
|
|
110
|
+
alias_method :bol?, :beginning_of_line?
|
|
111
|
+
|
|
112
|
+
def eos?
|
|
113
|
+
@pos >= @string.bytesize
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def rest?
|
|
117
|
+
!eos?
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# MatchData-like methods
|
|
121
|
+
|
|
122
|
+
def matched? = !Primitive.nil?(@last_match)
|
|
123
|
+
|
|
124
|
+
def matched = @last_match&.to_s
|
|
125
|
+
|
|
126
|
+
def [](group)
|
|
127
|
+
raise TypeError, 'no implicit conversion of Range into Integer' if Primitive.is_a?(group, Range)
|
|
128
|
+
|
|
129
|
+
if @last_match
|
|
130
|
+
@last_match[group]
|
|
131
|
+
else
|
|
132
|
+
nil
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def values_at(*groups) = @last_match&.values_at(*groups)
|
|
137
|
+
|
|
138
|
+
def captures = @last_match&.captures
|
|
139
|
+
|
|
140
|
+
def size = @last_match&.size
|
|
141
|
+
|
|
142
|
+
def pre_match = @last_match&.pre_match
|
|
143
|
+
|
|
144
|
+
def post_match = @last_match&.post_match
|
|
145
|
+
|
|
146
|
+
def named_captures = @last_match&.named_captures || {}
|
|
147
|
+
|
|
148
|
+
def matched_size
|
|
149
|
+
if @last_match
|
|
150
|
+
Primitive.match_data_byte_end(@last_match, 0) - Primitive.match_data_byte_begin(@last_match, 0)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Scan-like methods
|
|
155
|
+
|
|
156
|
+
def peek(length)
|
|
157
|
+
raise ArgumentError, 'negative string size (or size too big)' if length < 0
|
|
158
|
+
@string.byteslice(@pos, length)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def peek_byte = @string.getbyte(@pos)
|
|
162
|
+
|
|
163
|
+
def get_byte
|
|
164
|
+
return nil if eos?
|
|
165
|
+
|
|
166
|
+
byte = @string.byteslice(@pos, 1)
|
|
167
|
+
to = @pos + 1
|
|
168
|
+
@last_match = Primitive.matchdata_create_single_group(byte, @string, @pos, to)
|
|
169
|
+
@pos = to
|
|
170
|
+
byte
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def scan_byte
|
|
174
|
+
return nil if eos?
|
|
175
|
+
|
|
176
|
+
byte_value = @string.getbyte(@pos)
|
|
177
|
+
get_byte
|
|
178
|
+
byte_value
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def getch = scan(/./m)
|
|
182
|
+
|
|
183
|
+
def scan_integer(base: 10)
|
|
184
|
+
case base
|
|
185
|
+
when 10
|
|
186
|
+
scan(/[+-]?\d+/)&.to_i
|
|
187
|
+
when 16
|
|
188
|
+
scan(/[+-]?(0x)?[0-9a-fA-F]+/)&.to_i(16)
|
|
189
|
+
else
|
|
190
|
+
raise ArgumentError, "Unsupported integer base: #{base.inspect}, expected 10 or 16"
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def scan_full(pattern, advance_pointer, return_string)
|
|
195
|
+
if advance_pointer
|
|
196
|
+
if return_string
|
|
197
|
+
scan(pattern)
|
|
198
|
+
else
|
|
199
|
+
skip(pattern)
|
|
200
|
+
end
|
|
201
|
+
else
|
|
202
|
+
if return_string
|
|
203
|
+
check(pattern)
|
|
204
|
+
else
|
|
205
|
+
match?(pattern)
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
Primitive.always_split self, :scan_full
|
|
210
|
+
|
|
211
|
+
def search_full(pattern, advance_pointer, return_string)
|
|
212
|
+
if advance_pointer
|
|
213
|
+
if return_string
|
|
214
|
+
scan_until(pattern)
|
|
215
|
+
else
|
|
216
|
+
skip_until(pattern)
|
|
217
|
+
end
|
|
218
|
+
else
|
|
219
|
+
if return_string
|
|
220
|
+
check_until(pattern)
|
|
221
|
+
else
|
|
222
|
+
exist?(pattern)
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
Primitive.always_split self, :search_full
|
|
227
|
+
|
|
228
|
+
# Keep the following 8 methods in sync, they are small variations of one another
|
|
229
|
+
|
|
230
|
+
# Matches at start methods
|
|
231
|
+
|
|
232
|
+
# Matches at start, returns matched string, does not advance position
|
|
233
|
+
def check(pattern)
|
|
234
|
+
prev = @pos
|
|
235
|
+
if Primitive.is_a?(pattern, Regexp)
|
|
236
|
+
start = @fixed_anchor ? 0 : prev
|
|
237
|
+
@last_match = Primitive.regexp_match_at_start(pattern, @string, prev, start)
|
|
238
|
+
if @last_match
|
|
239
|
+
@last_match.to_s
|
|
240
|
+
end
|
|
241
|
+
else
|
|
242
|
+
pattern = Primitive.convert_with_to_str(pattern)
|
|
243
|
+
if rest.start_with?(pattern)
|
|
244
|
+
to = prev + pattern.bytesize
|
|
245
|
+
@last_match = Primitive.matchdata_create_single_group(pattern, @string, prev, to)
|
|
246
|
+
pattern
|
|
247
|
+
else
|
|
248
|
+
@last_match = nil
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
Primitive.always_split self, :check
|
|
253
|
+
|
|
254
|
+
# Matches at start, returns matched string, advances position
|
|
255
|
+
def scan(pattern)
|
|
256
|
+
prev = @pos
|
|
257
|
+
if Primitive.is_a?(pattern, Regexp)
|
|
258
|
+
start = @fixed_anchor ? 0 : prev
|
|
259
|
+
@last_match = Primitive.regexp_match_at_start(pattern, @string, prev, start)
|
|
260
|
+
if @last_match
|
|
261
|
+
@pos = Primitive.match_data_byte_end(@last_match, 0)
|
|
262
|
+
@last_match.to_s
|
|
263
|
+
end
|
|
264
|
+
else
|
|
265
|
+
pattern = Primitive.convert_with_to_str(pattern)
|
|
266
|
+
if rest.start_with?(pattern)
|
|
267
|
+
to = prev + pattern.bytesize
|
|
268
|
+
@last_match = Primitive.matchdata_create_single_group(pattern, @string, prev, to)
|
|
269
|
+
@pos = to
|
|
270
|
+
pattern
|
|
271
|
+
else
|
|
272
|
+
@last_match = nil
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
Primitive.always_split self, :scan
|
|
277
|
+
|
|
278
|
+
# Matches at start, returns matched bytesize, does not advance position
|
|
279
|
+
def match?(pattern)
|
|
280
|
+
prev = @pos
|
|
281
|
+
if Primitive.is_a?(pattern, Regexp)
|
|
282
|
+
start = @fixed_anchor ? 0 : prev
|
|
283
|
+
@last_match = Primitive.regexp_match_at_start(pattern, @string, prev, start)
|
|
284
|
+
if @last_match
|
|
285
|
+
to = Primitive.match_data_byte_end(@last_match, 0)
|
|
286
|
+
to - prev
|
|
287
|
+
end
|
|
288
|
+
else
|
|
289
|
+
pattern = Primitive.convert_with_to_str(pattern)
|
|
290
|
+
if rest.start_with?(pattern)
|
|
291
|
+
to = prev + pattern.bytesize
|
|
292
|
+
@last_match = Primitive.matchdata_create_single_group(pattern, @string, prev, to)
|
|
293
|
+
to - prev
|
|
294
|
+
else
|
|
295
|
+
@last_match = nil
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
Primitive.always_split self, :match?
|
|
300
|
+
|
|
301
|
+
# Matches at start, returns matched bytesize, advances position
|
|
302
|
+
def skip(pattern)
|
|
303
|
+
prev = @pos
|
|
304
|
+
if Primitive.is_a?(pattern, Regexp)
|
|
305
|
+
start = @fixed_anchor ? 0 : prev
|
|
306
|
+
@last_match = Primitive.regexp_match_at_start(pattern, @string, prev, start)
|
|
307
|
+
if @last_match
|
|
308
|
+
to = Primitive.match_data_byte_end(@last_match, 0)
|
|
309
|
+
@pos = to
|
|
310
|
+
to - prev
|
|
311
|
+
end
|
|
312
|
+
else
|
|
313
|
+
pattern = Primitive.convert_with_to_str(pattern)
|
|
314
|
+
if rest.start_with?(pattern)
|
|
315
|
+
to = prev + pattern.bytesize
|
|
316
|
+
@last_match = Primitive.matchdata_create_single_group(pattern, @string, prev, to)
|
|
317
|
+
@pos = to
|
|
318
|
+
to - prev
|
|
319
|
+
else
|
|
320
|
+
@last_match = nil
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
Primitive.always_split self, :skip
|
|
325
|
+
|
|
326
|
+
# Matches anywhere methods
|
|
327
|
+
|
|
328
|
+
# Matches anywhere, returns matched string, does not advance position
|
|
329
|
+
def check_until(pattern)
|
|
330
|
+
prev = @pos
|
|
331
|
+
if Primitive.is_a?(pattern, Regexp)
|
|
332
|
+
start = @fixed_anchor ? 0 : prev
|
|
333
|
+
@last_match = Primitive.regexp_search_with_start(pattern, @string, prev, start)
|
|
334
|
+
if @last_match
|
|
335
|
+
to = Primitive.match_data_byte_end(@last_match, 0)
|
|
336
|
+
@string.byteslice(prev, to - prev)
|
|
337
|
+
end
|
|
338
|
+
else
|
|
339
|
+
pattern = Primitive.convert_with_to_str(pattern)
|
|
340
|
+
if from = @string.byteindex(pattern, prev)
|
|
341
|
+
to = from + pattern.bytesize
|
|
342
|
+
@last_match = Primitive.matchdata_create_single_group(pattern, @string, from, to)
|
|
343
|
+
@string.byteslice(prev, to - prev)
|
|
344
|
+
else
|
|
345
|
+
@last_match = nil
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
Primitive.always_split self, :check_until
|
|
350
|
+
|
|
351
|
+
# Matches anywhere, returns matched string, advances position
|
|
352
|
+
def scan_until(pattern)
|
|
353
|
+
prev = @pos
|
|
354
|
+
if Primitive.is_a?(pattern, Regexp)
|
|
355
|
+
start = @fixed_anchor ? 0 : prev
|
|
356
|
+
@last_match = Primitive.regexp_search_with_start(pattern, @string, prev, start)
|
|
357
|
+
if @last_match
|
|
358
|
+
to = Primitive.match_data_byte_end(@last_match, 0)
|
|
359
|
+
@pos = to
|
|
360
|
+
@string.byteslice(prev, to - prev)
|
|
361
|
+
end
|
|
362
|
+
else
|
|
363
|
+
pattern = Primitive.convert_with_to_str(pattern)
|
|
364
|
+
if from = @string.byteindex(pattern, prev)
|
|
365
|
+
to = from + pattern.bytesize
|
|
366
|
+
@last_match = Primitive.matchdata_create_single_group(pattern, @string, from, to)
|
|
367
|
+
@pos = to
|
|
368
|
+
@string.byteslice(prev, to - prev)
|
|
369
|
+
else
|
|
370
|
+
@last_match = nil
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
Primitive.always_split self, :scan_until
|
|
375
|
+
|
|
376
|
+
# Matches anywhere, returns matched bytesize, does not advance position
|
|
377
|
+
def exist?(pattern)
|
|
378
|
+
prev = @pos
|
|
379
|
+
if Primitive.is_a?(pattern, Regexp)
|
|
380
|
+
start = @fixed_anchor ? 0 : prev
|
|
381
|
+
@last_match = Primitive.regexp_search_with_start(pattern, @string, prev, start)
|
|
382
|
+
if @last_match
|
|
383
|
+
to = Primitive.match_data_byte_end(@last_match, 0)
|
|
384
|
+
to - prev
|
|
385
|
+
end
|
|
386
|
+
else
|
|
387
|
+
pattern = Primitive.convert_with_to_str(pattern)
|
|
388
|
+
if from = @string.byteindex(pattern, prev)
|
|
389
|
+
to = from + pattern.bytesize
|
|
390
|
+
@last_match = Primitive.matchdata_create_single_group(pattern, @string, from, to)
|
|
391
|
+
to - prev
|
|
392
|
+
else
|
|
393
|
+
@last_match = nil
|
|
394
|
+
end
|
|
395
|
+
end
|
|
396
|
+
end
|
|
397
|
+
Primitive.always_split self, :exist?
|
|
398
|
+
|
|
399
|
+
# Matches anywhere, returns matched bytesize, advances position
|
|
400
|
+
def skip_until(pattern)
|
|
401
|
+
prev = @pos
|
|
402
|
+
if Primitive.is_a?(pattern, Regexp)
|
|
403
|
+
start = @fixed_anchor ? 0 : prev
|
|
404
|
+
@last_match = Primitive.regexp_search_with_start(pattern, @string, prev, start)
|
|
405
|
+
if @last_match
|
|
406
|
+
to = Primitive.match_data_byte_end(@last_match, 0)
|
|
407
|
+
@pos = to
|
|
408
|
+
to - prev
|
|
409
|
+
end
|
|
410
|
+
else
|
|
411
|
+
pattern = Primitive.convert_with_to_str(pattern)
|
|
412
|
+
if from = @string.byteindex(pattern, prev)
|
|
413
|
+
to = from + pattern.bytesize
|
|
414
|
+
@last_match = Primitive.matchdata_create_single_group(pattern, @string, from, to)
|
|
415
|
+
@pos = to
|
|
416
|
+
to - prev
|
|
417
|
+
else
|
|
418
|
+
@last_match = nil
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
end
|
|
422
|
+
Primitive.always_split self, :skip_until
|
|
423
|
+
end
|
data/lib/strscan.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
case RUBY_ENGINE
|
|
4
|
+
when 'ruby'
|
|
5
|
+
require 'strscan.so'
|
|
6
|
+
require_relative 'strscan/strscan'
|
|
7
|
+
when 'jruby'
|
|
8
|
+
require 'strscan.jar'
|
|
9
|
+
JRuby::Util.load_ext('org.jruby.ext.strscan.StringScannerLibrary')
|
|
10
|
+
require_relative 'strscan/strscan'
|
|
11
|
+
when 'truffleruby'
|
|
12
|
+
if RUBY_ENGINE_VERSION.to_i >= 34
|
|
13
|
+
require 'strscan/truffleruby'
|
|
14
|
+
else
|
|
15
|
+
$LOAD_PATH.delete __dir__
|
|
16
|
+
require 'strscan'
|
|
17
|
+
end
|
|
18
|
+
else
|
|
19
|
+
raise NotImplementedError, "Unknown Ruby: #{RUBY_ENGINE}"
|
|
20
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: strscan
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.1.
|
|
4
|
+
version: 3.1.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Minero Aoki
|
|
@@ -53,7 +53,9 @@ files:
|
|
|
53
53
|
- doc/strscan/strscan.md
|
|
54
54
|
- ext/strscan/extconf.rb
|
|
55
55
|
- ext/strscan/strscan.c
|
|
56
|
+
- lib/strscan.rb
|
|
56
57
|
- lib/strscan/strscan.rb
|
|
58
|
+
- lib/strscan/truffleruby.rb
|
|
57
59
|
homepage: https://github.com/ruby/strscan
|
|
58
60
|
licenses:
|
|
59
61
|
- Ruby
|
|
@@ -74,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
74
76
|
- !ruby/object:Gem::Version
|
|
75
77
|
version: '0'
|
|
76
78
|
requirements: []
|
|
77
|
-
rubygems_version: 4.0.
|
|
79
|
+
rubygems_version: 4.0.6
|
|
78
80
|
specification_version: 4
|
|
79
81
|
summary: Provides lexical scanning operations on a String.
|
|
80
82
|
test_files: []
|