Skip to content

Commit 3bbdfbe

Browse files
authored
Merge pull request #128 from sue445/feature/fix_rb_tracepoint_new
Fix rb_tracepoint_new
2 parents cd42350 + 6235265 commit 3bbdfbe

File tree

5 files changed

+96
-20
lines changed

5 files changed

+96
-20
lines changed

_tools/ruby_h_to_go/lib/ruby_header_parser.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
require_relative "ruby_header_parser/struct_definition"
99
require_relative "ruby_header_parser/type_definition"
1010
require_relative "ruby_header_parser/typeref_definition"
11+
require_relative "ruby_header_parser/util"
1112

1213
# Parser for ruby.h
1314
module RubyHeaderParser

_tools/ruby_h_to_go/lib/ruby_header_parser/parser.rb

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def initialize(header_dir)
1919

2020
# @return [Array<RubyHeaderParser::FunctionDefinition>]
2121
def extract_function_definitions
22-
stdout = `ctags --recurse --c-kinds=p --languages=C --language-force=C --fields=+n --extras=+q -f - #{header_dir}`
22+
stdout = `ctags --recurse --c-kinds=p --languages=C --language-force=C --fields=+nS --extras=+q -f - #{header_dir}`
2323

2424
stdout.each_line.with_object([]) do |line, definitions|
2525
parts = line.split("\t")
@@ -32,13 +32,13 @@ def extract_function_definitions
3232
if parts[2].end_with?(";$/;\"")
3333
parts[2].delete_prefix("/^").delete_suffix(";$/;\"")
3434
else
35-
line_num = parts[4].delete_prefix("line:").to_i
35+
line_num = Util.find_field(parts, "line").to_i
3636
read_definition_from_header_file(parts[1], line_num).delete_suffix(";")
3737
end
3838

3939
definition.gsub!(/\);.*/, ")")
4040

41-
args = parse_definition_args(function_name, definition)
41+
args = parse_definition_args(function_name, Util.find_field(parts, "signature"))
4242

4343
# Exclude functions with variable-length arguments
4444
next if args&.last&.type == "..."
@@ -182,31 +182,27 @@ def should_generate_type?(type_name)
182182
end
183183

184184
# @param function_name [String]
185-
# @param definition [String]
185+
# @param signature [String,nil]
186186
# @return [Array<RubyHeaderParser::ArgumentDefinition>]
187-
def parse_definition_args(function_name, definition)
188-
definition =~ /(?<=\()(.+)(?=\))/
189-
args = ::Regexp.last_match(1).split(",").map(&:strip)
187+
def parse_definition_args(function_name, signature)
188+
return [] unless signature
189+
190+
signature = signature.strip.delete_prefix("(").delete_suffix(")")
191+
return [] if signature.match?(/^void$/i)
192+
193+
args = Util.split_signature(signature)
190194

191195
arg_pos = 0
192196
args.map do |str|
193197
arg_pos += 1
194198
parts = str.split
195199

196200
if parts.count < 2
197-
type = parts[0]
198-
199-
if type =~ /^void$/i
200-
nil
201-
else
202-
name = "arg#{arg_pos}"
203-
204-
ArgumentDefinition.new(
205-
type:,
206-
name:,
207-
pointer: nil,
208-
)
209-
end
201+
ArgumentDefinition.new(
202+
type: parts[0],
203+
name: "arg#{arg_pos}",
204+
pointer: nil,
205+
)
210206
else
211207
loop do
212208
break unless parts[-1].start_with?("*")
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# frozen_string_literal: true
2+
3+
module RubyHeaderParser
4+
# util methods
5+
module Util
6+
# @param array [Array<String>]
7+
# @param field_name [String]
8+
# @return [String,nil]
9+
def self.find_field(array, field_name)
10+
array.each do |element|
11+
return element.delete_prefix("#{field_name}:") if element.start_with?("#{field_name}:")
12+
end
13+
14+
nil
15+
end
16+
17+
# @param signature [String]
18+
# @return [Array<String>]
19+
def self.split_signature(signature)
20+
signature.scan(/[^,]+\([^()]*\)|[^,]+/).map(&:strip)
21+
end
22+
end
23+
end

_tools/ruby_h_to_go/spec/ruby_header_parser/parser_spec.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,25 @@
6464
its(:typeref) { should eq typedef(type: "void", pointer: :ref) }
6565
its(:args) { should eq args }
6666
end
67+
68+
context "rb_tracepoint_new" do
69+
subject { definitions.find { |d| d.name == "rb_tracepoint_new" } }
70+
71+
let(:args) do
72+
[
73+
argument(type: "VALUE", name: "target_thread_not_supported_yet"),
74+
argument(type: "rb_event_flag_t", name: "events"),
75+
argument(type: "void", name: "arg3", pointer: :ref),
76+
argument(type: "void", name: "data", pointer: :ref),
77+
]
78+
end
79+
80+
its(:name) { should eq "rb_tracepoint_new" }
81+
its(:definition) { should eq "VALUE rb_tracepoint_new(VALUE target_thread_not_supported_yet, rb_event_flag_t events, void (*func)(VALUE, void *), void *data)" }
82+
its(:filepath) { should be_end_with "/ruby/debug.h" }
83+
its(:typeref) { should eq typedef(type: "VALUE") }
84+
its(:args) { should eq args }
85+
end
6786
end
6887

6988
describe "#extract_struct_definitions" do
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe RubyHeaderParser::Util do
4+
describe ".find_field" do
5+
subject { RubyHeaderParser::Util.find_field(array, field_name) }
6+
7+
let(:array) { %w[a b foo:bar] }
8+
9+
context "when exists field" do
10+
let(:field_name) { "foo" }
11+
12+
it { should eq "bar" }
13+
end
14+
15+
context "when not exists field" do
16+
let(:field_name) { "unknown" }
17+
18+
it { should eq nil }
19+
end
20+
end
21+
22+
describe ".split_signature" do
23+
subject { RubyHeaderParser::Util.split_signature(signature) }
24+
25+
context "simple case" do
26+
let(:signature) { "VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t proc, VALUE data2" }
27+
28+
it { should eq ["VALUE obj", "ID mid", "int argc", "const VALUE *argv", "rb_block_call_func_t proc", "VALUE data2"] }
29+
end
30+
31+
context "with function pointer" do
32+
let(:signature) { "VALUE target_thread_not_supported_yet,rb_event_flag_t events,void (* func)(VALUE,void *),void * data" }
33+
34+
it { should eq ["VALUE target_thread_not_supported_yet", "rb_event_flag_t events", "void (* func)(VALUE,void *)", "void * data"] }
35+
end
36+
end
37+
end

0 commit comments

Comments
 (0)