opal-onigmo 0.1.0 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 42b7f0d79bf4c8caa956996c2c3e719e830e4b7d5cdc36a37f259bad0817d4be
4
- data.tar.gz: 5d696a5c11e17b61aca28cefc0c275295dd9c5ffafd4e59cb173578e515d30db
3
+ metadata.gz: ec1caa38621cd815637b96284a30f5fb69f3049ccc759ff3e69a67ffc549c36a
4
+ data.tar.gz: 7d544017614820e67e952612a2fd5ef2d5496cfdcc01ed18b174630c2051f578
5
5
  SHA512:
6
- metadata.gz: 6183bcc0febb8a96b3380a91ba1a1073f77ed304acc19619adf2ba570108fc68085cd3517e32abd4339c647564d8ce8cc203639fb3ff8ee80a6411ccf5d53ad3
7
- data.tar.gz: e45bb5cbccbb07eb87ee9de044769aada834639012fe0fdfc8cfa0115308aaa6ad5c8548c9b0698eef34c963cd6da6be0c6e389b52381d9c1a718fc0c7cb339c
6
+ metadata.gz: e0d515da7c5d167ba85fee1cff7ffda106f6072568c0660c9e0997f0cff3499f621ae1472ac3c7175a2581a7b1b1c7f3ae33fea9868768bc3a250de7d419ce8c
7
+ data.tar.gz: f026ce0c670a78d70ff41f53c32e89f90c91e6ed68a65fb1cc2cd18d956aec49fbf5e1b3c1f82dba1a9947c79268f0388fc5ebb34c36901814841973a3f160fd
@@ -1,3 +1,3 @@
1
1
  [submodule "Onigmo"]
2
2
  path = Onigmo
3
- url = https://github.com/interscript/onigmo
3
+ url = https://github.com/interscript/Onigmo
data/Gemfile CHANGED
@@ -11,3 +11,4 @@ gem "pry"
11
11
  gem "opal", "~> 1.0"
12
12
  gem "opal-webassembly"
13
13
  gem "opal-rspec"
14
+ gem "mini_racer"
@@ -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
- opal (1.0.3)
16
- ast (>= 2.3.0)
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
- opal (~> 1.0)
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
- sh "cd Onigmo; sh ./build-wasm.sh; mv onigmo.wasm #{task.name}"
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"]
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ load "#{__dir__}/../exe/opal-repl-onigmo"
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'opal/repl'
4
+ require 'opal/onigmo'
5
+
6
+ Opal.append_paths '.'
7
+
8
+ repl = Opal::REPL.new.run ARGV.first
@@ -1,5 +1,5 @@
1
1
  module Opal
2
2
  module Onigmo
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.2"
4
4
  end
5
5
  end
@@ -27,5 +27,5 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
29
 
30
- spec.add_dependency "opal-webassembly"
30
+ spec.add_dependency "opal-webassembly", "~> 0.1"
31
31
  end
@@ -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
@@ -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
@@ -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] = Onigmo::FFI.library.exports[:OnigDefaultCaseFoldFlag].value
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
@@ -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 = Onigmo::FFI.context do
32
- @ffi_regexpptr = Onigmo::FFI::RegexpPtr.new
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.new
39
+ ffi_errorinfo = Onigmo::FFI::ErrorInfo.cached
35
40
 
36
- ffi_pattern = ::FFI::Pointer.from_string(@pattern)
41
+ ffi_pattern = Onigmo.buffer(@pattern)
37
42
  ffi_pattern_end = ffi_pattern + (@pattern.length * 2)
38
43
 
39
- ffi_options.options = Onigmo::FFI::ONIG_OPTION_NONE
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(@ffi_regexpptr, ffi_pattern, ffi_pattern_end,
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
- @ffi_regexp = @ffi_regexpptr.value
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 = ::FFI::Pointer.from_string(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
- def ffi_region
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
- matches = matches(str)
115
+ ms = matches
96
116
  region = ffi_region
97
117
  out = {
98
118
  input: str,
99
119
  index: region[0][0]/2,
100
- length: matches.length,
120
+ length: ms.length,
101
121
  slice: proc { |i| matches[i..-1] }
102
122
  }
103
123
  out = out.to_n
104
- matches.each_with_index { |m,i| `out[#{i}] = #{m}` }
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
@@ -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.0
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.0.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: []