Skip to content

Commit 5a8fd96

Browse files
authored
Merge pull request #134 from sue445/feature/move_to_data_yaml
Move to `RubyHeaderParser::Data`
2 parents 46c9000 + 70de58c commit 5a8fd96

File tree

7 files changed

+193
-89
lines changed

7 files changed

+193
-89
lines changed

.rubocop_todo.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# This configuration was generated by
22
# `rubocop --auto-gen-config`
3-
# on 2024-09-17 16:12:35 UTC using RuboCop version 1.66.1.
3+
# on 2024-09-18 15:36:12 UTC using RuboCop version 1.66.1.
44
# The point is for the user to remove these configuration records
55
# one by one as the offenses are removed from the code base.
66
# Note that changes in the inspected code, or installation of new
@@ -25,7 +25,7 @@ Metrics/BlockNesting:
2525
# Offense count: 3
2626
# Configuration parameters: CountComments, CountAsOne.
2727
Metrics/ClassLength:
28-
Max: 175
28+
Max: 131
2929

3030
# Offense count: 4
3131
# Configuration parameters: AllowedMethods, AllowedPatterns.

_tools/ruby_h_to_go/lib/ruby_header_parser.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require "yaml"
44

55
require_relative "ruby_header_parser/argument_definition"
6+
require_relative "ruby_header_parser/data"
67
require_relative "ruby_header_parser/function_definition"
78
require_relative "ruby_header_parser/parser"
89
require_relative "ruby_header_parser/struct_definition"
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# frozen_string_literal: true
2+
3+
module RubyHeaderParser
4+
# Manager for `data.yml`
5+
class Data
6+
# @!attribute [r] data
7+
# @return [Hash]
8+
attr_reader :data
9+
10+
def initialize
11+
yaml = File.read(File.join(__dir__, "data.yml"))
12+
@data = YAML.safe_load(yaml, permitted_classes: [Regexp])
13+
end
14+
15+
# @param function_name [String]
16+
# @param index [Integer] arg position (0 origin)
17+
# @return [Symbol] :ref, :array
18+
def function_arg_pointer_hint(function_name:, index:)
19+
pointer_hint = data["function"]["pointer_hint"].dig(function_name, index)
20+
return pointer_hint.to_sym if pointer_hint
21+
22+
:ref
23+
end
24+
25+
# Whether generate C function to go
26+
# @param function_name [String]
27+
# @return [Boolean]
28+
def should_generate_function?(function_name)
29+
function_name = function_name.downcase
30+
31+
return false if data["function"]["deny_name"].any? { |format| format === function_name } # rubocop:disable Style/CaseEquality
32+
33+
data["function"]["allow_name"].any? { |format| format === function_name } # rubocop:disable Style/CaseEquality
34+
end
35+
36+
# Whether generate C struct to go
37+
# @param struct_name [String]
38+
# @return [Boolean]
39+
def should_generate_struct?(struct_name)
40+
struct_name = struct_name.downcase
41+
42+
data["struct"]["allow_name"].any? { |format| format === struct_name } # rubocop:disable Style/CaseEquality
43+
end
44+
45+
# Whether generate C type to go
46+
# @param type_name [String]
47+
# @return [Boolean]
48+
def should_generate_type?(type_name)
49+
type_name = type_name.downcase
50+
51+
data["type"]["allow_name"].any? { |format| format === type_name } # rubocop:disable Style/CaseEquality
52+
end
53+
end
54+
end
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
function:
2+
allow_name:
3+
- !ruby/regexp /^rb_/
4+
- !ruby/regexp /^rstring_/
5+
6+
deny_name:
7+
# deprecated functions
8+
- rb_check_safe_str
9+
- rb_clear_constant_cache
10+
- rb_clone_setup
11+
- rb_complex_polar
12+
- rb_data_object_alloc
13+
- rb_data_object_get_warning
14+
- rb_data_object_wrap_warning
15+
- rb_data_typed_object_alloc
16+
- rb_dup_setup
17+
- rb_gc_force_recycle
18+
- rb_iterate
19+
- rb_obj_infect
20+
- rb_obj_infect_raw
21+
- rb_obj_taint
22+
- rb_obj_taint_raw
23+
- rb_obj_taintable
24+
- rb_obj_tainted
25+
- rb_obj_tainted_raw
26+
- rb_scan_args_length_mismatch
27+
- rb_varargs_bad_length
28+
29+
# internal functions in ruby.h
30+
- rb_scan_args_bad_format
31+
32+
pointer_hint:
33+
rb_funcallv:
34+
3: array
35+
rb_funcallv_public:
36+
3: array
37+
38+
struct:
39+
allow_name:
40+
- !ruby/regexp /^rb_/
41+
42+
type:
43+
allow_name:
44+
- !ruby/regexp /^rb_/
45+
- !ruby/regexp /^st_/
46+
- id
47+
- value

_tools/ruby_h_to_go/lib/ruby_header_parser/parser.rb

Lines changed: 6 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ class Parser
88
attr_reader :header_dir
99

1010
# @!attribute [r] data
11-
# @return [Hash]
11+
# @return [RubyHeaderParser::Data]
1212
attr_reader :data
1313

1414
# @param header_dir [String]
1515
def initialize(header_dir)
1616
@header_dir = header_dir
17-
@data = YAML.load_file(File.join(__dir__, "ruby_header_parser.yml"))
17+
@data = Data.new
1818
end
1919

2020
# @return [Array<RubyHeaderParser::FunctionDefinition>]
@@ -26,7 +26,7 @@ def extract_function_definitions
2626

2727
function_name = parts[0]
2828

29-
next unless should_generate_function?(function_name)
29+
next unless data.should_generate_function?(function_name)
3030

3131
definition =
3232
if parts[2].end_with?(";$/;\"")
@@ -62,7 +62,7 @@ def extract_struct_definitions
6262

6363
struct_name = parts[0]
6464

65-
next unless should_generate_struct?(struct_name)
65+
next unless data.should_generate_struct?(struct_name)
6666

6767
definitions << StructDefinition.new(
6868
name: struct_name,
@@ -80,7 +80,7 @@ def extract_type_definitions
8080

8181
type_name = parts[0]
8282

83-
next unless should_generate_type?(type_name)
83+
next unless data.should_generate_type?(type_name)
8484

8585
definitions << TypeDefinition.new(
8686
name: type_name,
@@ -91,48 +91,6 @@ def extract_type_definitions
9191

9292
private
9393

94-
ALLOW_FUNCTION_NAME_PREFIXES = %w[rb_ rstring_].freeze
95-
96-
DENY_FUNCTION_NAMES = [
97-
# deprecated functions
98-
"rb_check_safe_str",
99-
"rb_clear_constant_cache",
100-
"rb_clone_setup",
101-
"rb_complex_polar",
102-
"rb_data_object_alloc",
103-
"rb_data_object_get_warning",
104-
"rb_data_object_wrap_warning",
105-
"rb_data_typed_object_alloc",
106-
"rb_dup_setup",
107-
"rb_gc_force_recycle",
108-
"rb_iterate",
109-
"rb_obj_infect",
110-
"rb_obj_infect_raw",
111-
"rb_obj_taint",
112-
"rb_obj_taint_raw",
113-
"rb_obj_taintable",
114-
"rb_obj_tainted",
115-
"rb_obj_tainted_raw",
116-
"rb_scan_args_length_mismatch",
117-
"rb_varargs_bad_length",
118-
119-
# internal functions in ruby.h
120-
"rb_scan_args_bad_format",
121-
].freeze
122-
123-
# Whether generate C function to go
124-
# @param function_name [String]
125-
# @return [Boolean]
126-
def should_generate_function?(function_name)
127-
function_name = function_name.downcase
128-
129-
return false if DENY_FUNCTION_NAMES.include?(function_name)
130-
131-
return true if ALLOW_FUNCTION_NAME_PREFIXES.any? { |prefix| function_name.start_with?(prefix) }
132-
133-
false
134-
end
135-
13694
# @param file [String]
13795
# @param line_num [Integer]
13896
def read_definition_from_header_file(file, line_num)
@@ -149,29 +107,6 @@ def read_definition_from_header_file(file, line_num)
149107
""
150108
end
151109

152-
# Whether generate C struct to go
153-
# @param struct_name [String]
154-
# @return [Boolean]
155-
def should_generate_struct?(struct_name)
156-
struct_name = struct_name.downcase
157-
158-
struct_name.start_with?("rb_")
159-
end
160-
161-
ALLOW_TYPE_NAME_PREFIXES = %w[rb_ st_].freeze
162-
ALLOW_TYPE_NAMES = %w[id value].freeze
163-
164-
# Whether generate C type to go
165-
# @param type_name [String]
166-
# @return [Boolean]
167-
def should_generate_type?(type_name)
168-
type_name = type_name.downcase
169-
170-
return true if ALLOW_TYPE_NAME_PREFIXES.any? { |prefix| type_name.start_with?(prefix) }
171-
172-
ALLOW_TYPE_NAMES.include?(type_name)
173-
end
174-
175110
# @param function_name [String]
176111
# @param signature [String,nil]
177112
# @return [Array<RubyHeaderParser::ArgumentDefinition>]
@@ -222,7 +157,7 @@ def parse_definition_args(function_name, signature)
222157

223158
if type.match?(/\*+$/)
224159
type = type.gsub(/\*+$/, "").strip
225-
pointer ||= function_arg_pointer_hint(function_name, arg_pos - 1)
160+
pointer ||= data.function_arg_pointer_hint(function_name:, index: arg_pos - 1)
226161
elsif /^void\s*\s/.match?(type) || /\(.*\)/.match?(type)
227162
# function pointer (e.g. void *(*func)(void *)) is treated as `void*`
228163
type = "void"
@@ -239,16 +174,6 @@ def parse_definition_args(function_name, signature)
239174
end.compact
240175
end
241176

242-
# @param function_name [String]
243-
# @param index [Integer] arg position
244-
# @return [Symbol] :ref, :array
245-
def function_arg_pointer_hint(function_name, index)
246-
pointer_hint = data["pointer_hint"]["function"].dig(function_name, index)
247-
return pointer_hint.to_sym if pointer_hint
248-
249-
:ref
250-
end
251-
252177
# @param definition [String]
253178
# @param function_name [String]
254179
# @return [RubyHeaderParser::TyperefDefinition]

_tools/ruby_h_to_go/lib/ruby_header_parser/ruby_header_parser.yml

Lines changed: 0 additions & 6 deletions
This file was deleted.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe RubyHeaderParser::Data do
4+
let(:data) { RubyHeaderParser::Data.new }
5+
6+
describe "#function_arg_pointer_hint" do
7+
subject { data.function_arg_pointer_hint(function_name:, index:) }
8+
9+
context "found in data.yml" do
10+
let(:function_name) { "rb_funcallv" }
11+
let(:index) { 3 }
12+
13+
it { should eq :array }
14+
end
15+
16+
context "not found in data.yml" do
17+
let(:function_name) { "rb_funcallv" }
18+
let(:index) { 4 }
19+
20+
it { should eq :ref }
21+
end
22+
end
23+
24+
describe "#should_generate_function?" do
25+
subject { data.should_generate_function?(function_name) }
26+
27+
context "rb function (denied)" do
28+
let(:function_name) { "rb_check_safe_str" }
29+
30+
it { should eq false }
31+
end
32+
33+
context "rb function (allowed)" do
34+
let(:function_name) { "rb_define_class" }
35+
36+
it { should eq true }
37+
end
38+
39+
context "no rb function" do
40+
let(:function_name) { "sprintf" }
41+
42+
it { should eq false }
43+
end
44+
end
45+
46+
describe "#should_generate_struct?" do
47+
subject { data.should_generate_struct?(struct_name) }
48+
49+
context "rb struct" do
50+
let(:struct_name) { "rb_random_struct" }
51+
52+
it { should eq true }
53+
end
54+
55+
context "non rb struct" do
56+
let(:struct_name) { "fuga" }
57+
58+
it { should eq false }
59+
end
60+
end
61+
62+
describe "#should_generate_type?" do
63+
subject { data.should_generate_type?(type_name) }
64+
65+
context "rb type" do
66+
let(:type_name) { "rb_data_type_t" }
67+
68+
it { should eq true }
69+
end
70+
71+
context "VALUE" do
72+
let(:type_name) { "VALUE" }
73+
74+
it { should eq true }
75+
end
76+
77+
context "unknown" do
78+
let(:type_name) { "unknown" }
79+
80+
it { should eq false }
81+
end
82+
end
83+
end

0 commit comments

Comments
 (0)