opal-onigmo 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitmodules +1 -1
- data/Gemfile +1 -0
- data/Gemfile.lock +5 -4
- data/Rakefile +6 -3
- data/bin/opal-repl-onigmo +4 -0
- data/exe/opal-repl-onigmo +8 -0
- data/lib/opal/onigmo/version.rb +1 -1
- data/opal-onigmo.gemspec +1 -1
- data/opal/onigmo.rb +13 -0
- data/opal/onigmo/core_ext.rb +53 -0
- data/opal/onigmo/ffi.rb +11 -2
- data/opal/onigmo/onigmo-wasm.wasm +0 -0
- data/opal/onigmo/regexp.rb +45 -20
- data/spec-opal/regexp_spec.rb +14 -0
- metadata +13 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec1caa38621cd815637b96284a30f5fb69f3049ccc759ff3e69a67ffc549c36a
|
4
|
+
data.tar.gz: 7d544017614820e67e952612a2fd5ef2d5496cfdcc01ed18b174630c2051f578
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0d515da7c5d167ba85fee1cff7ffda106f6072568c0660c9e0997f0cff3499f621ae1472ac3c7175a2581a7b1b1c7f3ae33fea9868768bc3a250de7d419ce8c
|
7
|
+
data.tar.gz: f026ce0c670a78d70ff41f53c32e89f90c91e6ed68a65fb1cc2cd18d956aec49fbf5e1b3c1f82dba1a9947c79268f0388fc5ebb34c36901814841973a3f160fd
|
data/.gitmodules
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -11,10 +11,10 @@ GEM
|
|
11
11
|
coderay (1.1.3)
|
12
12
|
concurrent-ruby (1.1.7)
|
13
13
|
diff-lcs (1.4.4)
|
14
|
+
libv8 (8.4.255.0)
|
14
15
|
method_source (1.0.0)
|
15
|
-
|
16
|
-
|
17
|
-
parser (~> 2.6)
|
16
|
+
mini_racer (0.3.1)
|
17
|
+
libv8 (~> 8.4.255)
|
18
18
|
opal-rspec (0.8.0.alpha2)
|
19
19
|
opal (>= 0.11, < 1.1)
|
20
20
|
opal-sprockets
|
@@ -54,7 +54,8 @@ PLATFORMS
|
|
54
54
|
ruby
|
55
55
|
|
56
56
|
DEPENDENCIES
|
57
|
-
|
57
|
+
mini_racer
|
58
|
+
opal!
|
58
59
|
opal-onigmo!
|
59
60
|
opal-rspec
|
60
61
|
opal-webassembly
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ Opal::RSpec::RakeTask.new("spec-opal") do |server, task|
|
|
9
9
|
require 'opal/onigmo'
|
10
10
|
end
|
11
11
|
|
12
|
-
task :generate => ['opal/onigmo/constants.rb', 'opal/onigmo/onigmo.wasm'] do
|
12
|
+
task :generate => ['opal/onigmo/constants.rb', 'opal/onigmo/onigmo-wasm.wasm'] do
|
13
13
|
end
|
14
14
|
|
15
15
|
def render_template(template, output, vars)
|
@@ -28,8 +28,11 @@ file 'opal/onigmo/constants.rb' => ['opal/onigmo/constants.rb.erb', 'Onigmo/onig
|
|
28
28
|
)
|
29
29
|
end
|
30
30
|
|
31
|
-
file 'opal/onigmo/onigmo.wasm' => ['Onigmo/build-wasm.sh'] do |task|
|
32
|
-
|
31
|
+
file 'opal/onigmo/onigmo-wasm.wasm' => ['Onigmo/build-wasm.sh'] do |task|
|
32
|
+
if File.exist? __dir__+"/../../wasi-sdk-11.0/share/wasi-sysroot/"
|
33
|
+
env = "BUILD=wasi WASI_PATH=#{__dir__}/../../wasi-sdk-11.0/share/wasi-sysroot/"
|
34
|
+
end
|
35
|
+
sh "cd Onigmo; #{env} sh ./build-wasm.sh; mv onigmo.wasm ../opal/onigmo/onigmo-wasm.wasm"
|
33
36
|
end
|
34
37
|
|
35
38
|
task :default => [:spec, "spec-opal"]
|
data/lib/opal/onigmo/version.rb
CHANGED
data/opal-onigmo.gemspec
CHANGED
data/opal/onigmo.rb
CHANGED
@@ -4,4 +4,17 @@ require 'onigmo/ffi'
|
|
4
4
|
require 'onigmo/regexp'
|
5
5
|
|
6
6
|
module Onigmo
|
7
|
+
def self.buffer(str)
|
8
|
+
Onigmo::FFI.context do
|
9
|
+
@buffer_size ||= 1024
|
10
|
+
@buffer ||= ::FFI::Pointer.new(:uint8, 640000) # 640 kB of RAM will be enough for everybody
|
11
|
+
current_size = @buffer_size
|
12
|
+
while str.length*2 > @buffer_size
|
13
|
+
@buffer_size *= 2
|
14
|
+
end
|
15
|
+
@buffer.resize(@buffer_size) if current_size != @buffer_size
|
16
|
+
@buffer.write_string(str)
|
17
|
+
@buffer
|
18
|
+
end
|
19
|
+
end
|
7
20
|
end
|
data/opal/onigmo/core_ext.rb
CHANGED
@@ -18,4 +18,57 @@ class String
|
|
18
18
|
match_before_onigmo?(re, pos, &block)
|
19
19
|
end
|
20
20
|
end
|
21
|
+
|
22
|
+
alias gsub_before_onigmo gsub
|
23
|
+
def gsub(from, to = undefined, &block)
|
24
|
+
if Onigmo::Regexp === from
|
25
|
+
out = []
|
26
|
+
index = 0
|
27
|
+
loop do
|
28
|
+
o = from.evaluate(self, index)
|
29
|
+
if o == nil # not found anymore
|
30
|
+
out << self[index..-1]
|
31
|
+
break
|
32
|
+
end
|
33
|
+
bgn, fin = from.ffi_region[0].map { |i| i/2 }
|
34
|
+
matches = from.matches
|
35
|
+
|
36
|
+
md = MatchData.new(from, from.js_matches(self))
|
37
|
+
|
38
|
+
out << self[index...bgn]
|
39
|
+
|
40
|
+
if block && `to === undefined`
|
41
|
+
out << block.(matches[0])
|
42
|
+
else
|
43
|
+
_to = to.JS.replace(%x{/([\\]+)([0-9+&`'\\])/g}) do |original, slashes, command|
|
44
|
+
if slashes.length % 2 == 0
|
45
|
+
original
|
46
|
+
else
|
47
|
+
slashes = slashes[0..-2]
|
48
|
+
case command
|
49
|
+
when "+", "&", "`", "'"
|
50
|
+
raise NotImplementedError
|
51
|
+
when "\\"
|
52
|
+
slashes + "\\"
|
53
|
+
else
|
54
|
+
slashes + ( matches[command.to_i] || "" )
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
out << _to
|
59
|
+
end
|
60
|
+
|
61
|
+
if bgn == fin
|
62
|
+
fin += 1
|
63
|
+
out << self[bgn]
|
64
|
+
end
|
65
|
+
|
66
|
+
index = fin
|
67
|
+
end
|
68
|
+
|
69
|
+
out.join
|
70
|
+
else
|
71
|
+
gsub_before_onigmo(from, to, &block)
|
72
|
+
end
|
73
|
+
end
|
21
74
|
end
|
data/opal/onigmo/ffi.rb
CHANGED
@@ -10,6 +10,7 @@ module Onigmo
|
|
10
10
|
ffi_lib "onigmo/onigmo-wasm"
|
11
11
|
|
12
12
|
class Regexp < ::FFI::Struct
|
13
|
+
# This is defined mostly for debugging purposes
|
13
14
|
layout :p, :pointer,
|
14
15
|
:used, :uint,
|
15
16
|
:alloc, :uint,
|
@@ -77,13 +78,15 @@ module Onigmo
|
|
77
78
|
|
78
79
|
def self.default_compile_info
|
79
80
|
@default ||= Onigmo::FFI.context do
|
81
|
+
casefold = Onigmo::FFI.library.exports[:OnigDefaultCaseFoldFlag]
|
82
|
+
casefold = casefold.value if casefold.respond_to? :value
|
80
83
|
new.tap do |ci|
|
81
84
|
ci[:num_of_elements] = 5
|
82
85
|
ci[:pattern_enc] = Onigmo::FFI.library.exports[:OnigEncodingUTF_16LE]
|
83
86
|
ci[:target_enc] = Onigmo::FFI.library.exports[:OnigEncodingUTF_16LE]
|
84
87
|
ci[:syntax] = Onigmo::FFI.library.exports[:OnigSyntaxRuby]
|
85
88
|
ci[:option] = Onigmo::FFI::ONIG_OPTION_NONE # To be overwritten
|
86
|
-
ci[:case_fold_flag] =
|
89
|
+
ci[:case_fold_flag] = casefold
|
87
90
|
end
|
88
91
|
end
|
89
92
|
end
|
@@ -101,13 +104,19 @@ module Onigmo
|
|
101
104
|
layout :enc, :pointer,
|
102
105
|
:par, :pointer,
|
103
106
|
:par_end, :pointer
|
107
|
+
|
108
|
+
def self.cached
|
109
|
+
@cached ||= new
|
110
|
+
end
|
104
111
|
end
|
105
112
|
|
106
113
|
attach_function :onig_new_deluxe, [RegexpPtr, :pointer, :pointer, CompileInfo, ErrorInfo], :int
|
107
|
-
attach_function :onig_region_new, [], Region
|
108
114
|
attach_function :onig_match, [Regexp, :pointer, :pointer, :pointer, Region, :uint], :int
|
109
115
|
attach_function :onig_search, [Regexp, :pointer, :pointer, :pointer, :pointer, Region, :uint], :int
|
116
|
+
attach_function :onig_free, [Regexp], :void
|
110
117
|
|
118
|
+
attach_function :onig_region_new, [], Region
|
119
|
+
attach_function :onig_region_free, [Region, :int], :void
|
111
120
|
end
|
112
121
|
|
113
122
|
Onigmo::FFI.library.memory.grow(128)
|
Binary file
|
data/opal/onigmo/regexp.rb
CHANGED
@@ -24,28 +24,34 @@ module Onigmo
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def initialize pattern, options = ''
|
27
|
+
if pattern.is_a? Onigmo::Regexp
|
28
|
+
pattern = pattern.pattern
|
29
|
+
end
|
30
|
+
|
27
31
|
@lastIndex = 0
|
28
32
|
@pattern = pattern.encode("UTF-16LE")
|
29
33
|
@options = options
|
30
34
|
|
31
|
-
out =
|
32
|
-
|
35
|
+
out = nil
|
36
|
+
Onigmo::FFI.context do
|
37
|
+
ffi_regexpptr = Onigmo::FFI::RegexpPtr.new
|
33
38
|
ffi_options = Onigmo::FFI::CompileInfo.default_compile_info
|
34
|
-
ffi_errorinfo = Onigmo::FFI::ErrorInfo.
|
39
|
+
ffi_errorinfo = Onigmo::FFI::ErrorInfo.cached
|
35
40
|
|
36
|
-
ffi_pattern =
|
41
|
+
ffi_pattern = Onigmo.buffer(@pattern)
|
37
42
|
ffi_pattern_end = ffi_pattern + (@pattern.length * 2)
|
38
43
|
|
39
|
-
ffi_options.options
|
44
|
+
ffi_options.options = Onigmo::FFI::ONIG_OPTION_NONE
|
40
45
|
ffi_options.options |= Onigmo::FFI::ONIG_OPTION_IGNORECASE if options.include? "i"
|
41
46
|
ffi_options.options |= Onigmo::FFI::ONIG_OPTION_MULTILINE if options.include? "m"
|
42
47
|
ffi_options.options |= Onigmo::FFI::ONIG_OPTION_EXTEND if options.include? "x"
|
43
48
|
|
44
|
-
Onigmo::FFI.onig_new_deluxe(
|
49
|
+
out = Onigmo::FFI.onig_new_deluxe(ffi_regexpptr, ffi_pattern, ffi_pattern_end,
|
45
50
|
ffi_options, ffi_errorinfo)
|
46
|
-
end
|
47
51
|
|
48
|
-
|
52
|
+
@ffi_regexp = ffi_regexpptr.value
|
53
|
+
ffi_regexpptr.free
|
54
|
+
end
|
49
55
|
|
50
56
|
@exec = proc { |re| js_exec(re) }
|
51
57
|
|
@@ -54,6 +60,8 @@ module Onigmo
|
|
54
60
|
end
|
55
61
|
end
|
56
62
|
|
63
|
+
attr_accessor :pattern, :options
|
64
|
+
|
57
65
|
def ffi_evaluate string, offset = 0
|
58
66
|
offset ||= 0
|
59
67
|
|
@@ -61,21 +69,37 @@ module Onigmo
|
|
61
69
|
|
62
70
|
string = string.encode("UTF-16LE")
|
63
71
|
|
64
|
-
Onigmo::FFI.context do
|
65
|
-
ffi_string =
|
72
|
+
out = Onigmo::FFI.context do
|
73
|
+
ffi_string = Onigmo.buffer(string)
|
66
74
|
ffi_string_end = ffi_string + (string.length * 2)
|
67
75
|
ffi_string_offset = ffi_string + offset * 2
|
68
76
|
|
69
77
|
Onigmo::FFI.onig_search(@ffi_regexp, ffi_string, ffi_string_end, ffi_string_offset,
|
70
78
|
ffi_string_end, @ffi_region, Onigmo::FFI::ONIG_OPTION_NONE)
|
71
79
|
end
|
72
|
-
end
|
73
80
|
|
74
|
-
|
75
|
-
@ffi_region[:num_regs].times.map do |i|
|
81
|
+
@region = @ffi_region[:num_regs].times.map do |i|
|
76
82
|
[@ffi_region[:beg].get(:long, i*4),
|
77
83
|
@ffi_region[:end].get(:long, i*4) ]
|
78
84
|
end
|
85
|
+
|
86
|
+
Onigmo::FFI.onig_region_free(@ffi_region, 1)
|
87
|
+
|
88
|
+
@matches = @region.map { |b,e| string[b/2...e/2] }
|
89
|
+
|
90
|
+
out
|
91
|
+
end
|
92
|
+
|
93
|
+
def ffi_region
|
94
|
+
@region
|
95
|
+
end
|
96
|
+
|
97
|
+
def matches
|
98
|
+
@matches
|
99
|
+
end
|
100
|
+
|
101
|
+
def ffi_free
|
102
|
+
Onigmo::FFI.onig_free(@ffi_regexp)
|
79
103
|
end
|
80
104
|
|
81
105
|
def evaluate string, offset = 0
|
@@ -87,21 +111,17 @@ module Onigmo
|
|
87
111
|
end
|
88
112
|
end
|
89
113
|
|
90
|
-
def matches(str)
|
91
|
-
ffi_region.map { |b,e| str[b/2...e/2] }
|
92
|
-
end
|
93
|
-
|
94
114
|
def js_matches(str)
|
95
|
-
|
115
|
+
ms = matches
|
96
116
|
region = ffi_region
|
97
117
|
out = {
|
98
118
|
input: str,
|
99
119
|
index: region[0][0]/2,
|
100
|
-
length:
|
120
|
+
length: ms.length,
|
101
121
|
slice: proc { |i| matches[i..-1] }
|
102
122
|
}
|
103
123
|
out = out.to_n
|
104
|
-
|
124
|
+
ms.each_with_index { |m,i| `out[#{i}] = #{m}` }
|
105
125
|
@lastIndex = region[0][1]/2
|
106
126
|
out
|
107
127
|
end
|
@@ -114,5 +134,10 @@ module Onigmo
|
|
114
134
|
nil.to_n
|
115
135
|
end
|
116
136
|
end
|
137
|
+
|
138
|
+
def reset
|
139
|
+
@lastIndex = 0
|
140
|
+
self
|
141
|
+
end
|
117
142
|
end
|
118
143
|
end
|
data/spec-opal/regexp_spec.rb
CHANGED
@@ -20,10 +20,24 @@ RSpec.describe Onigmo::Regexp do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should support String#gsub" do
|
23
|
+
require 'onigmo/core_ext'
|
23
24
|
re = Onigmo::Regexp.new('aa')
|
24
25
|
expect('aababaaaabbaaaba'.gsub(re, 'ZZ')).to eq('ZZbabZZZZbbZZaba')
|
25
26
|
end
|
26
27
|
|
28
|
+
it "should support String#gsub with $ correctly" do
|
29
|
+
require 'onigmo/core_ext'
|
30
|
+
re = Onigmo::Regexp.new('$')
|
31
|
+
expect('lol'.gsub(re, '2')).to eq('lol2')
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should support String#gsub with backparameters correctly" do
|
35
|
+
require 'onigmo/core_ext'
|
36
|
+
re = Onigmo::Regexp.new('(?<=te)(..)(?=st)')
|
37
|
+
expect('texxst'.gsub(re, '\1\1')).to eq('texxxxst')
|
38
|
+
expect('teyyst'.gsub(re) { "123" }).to eq('te123st')
|
39
|
+
end
|
40
|
+
|
27
41
|
it "should support String#sub" do
|
28
42
|
re = Onigmo::Regexp.new('aa')
|
29
43
|
expect('aababaaaabbaaaba'.sub(re, 'ZZ')).to eq('ZZbabaaaabbaaaba')
|
metadata
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opal-onigmo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
11
|
date: 2020-10-05 00:00:00.000000000 Z
|
@@ -14,21 +14,22 @@ dependencies:
|
|
14
14
|
name: opal-webassembly
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
19
|
+
version: '0.1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
26
|
+
version: '0.1'
|
27
27
|
description: Execute regexps in Opal with a native Ruby regexp engine - Onigmo - compiled
|
28
28
|
using clang to WebAssembly
|
29
29
|
email:
|
30
30
|
- open.source@ribose.com
|
31
|
-
executables:
|
31
|
+
executables:
|
32
|
+
- opal-repl-onigmo
|
32
33
|
extensions: []
|
33
34
|
extra_rdoc_files: []
|
34
35
|
files:
|
@@ -44,7 +45,9 @@ files:
|
|
44
45
|
- README.adoc
|
45
46
|
- Rakefile
|
46
47
|
- bin/console
|
48
|
+
- bin/opal-repl-onigmo
|
47
49
|
- bin/setup
|
50
|
+
- exe/opal-repl-onigmo
|
48
51
|
- lib/opal/onigmo.rb
|
49
52
|
- lib/opal/onigmo/version.rb
|
50
53
|
- opal-onigmo.gemspec
|
@@ -64,7 +67,7 @@ metadata:
|
|
64
67
|
homepage_uri: https://github.com/interscript/opal-onigmo
|
65
68
|
source_code_uri: https://github.com/interscript/opal-onigmo
|
66
69
|
changelog_uri: https://github.com/interscript/opal-onigmo/commits/master
|
67
|
-
post_install_message:
|
70
|
+
post_install_message:
|
68
71
|
rdoc_options: []
|
69
72
|
require_paths:
|
70
73
|
- lib
|
@@ -79,8 +82,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
82
|
- !ruby/object:Gem::Version
|
80
83
|
version: '0'
|
81
84
|
requirements: []
|
82
|
-
rubygems_version: 3.
|
83
|
-
signing_key:
|
85
|
+
rubygems_version: 3.1.2
|
86
|
+
signing_key:
|
84
87
|
specification_version: 4
|
85
88
|
summary: Execute regexps with Opal using Onigmo
|
86
89
|
test_files: []
|