Skip to content

Commit c5a5bad

Browse files
authored
Merge pull request #139 from sue445/feature/replace_all_bindings
Replace all bindings with auto-generated code
2 parents 5984c1f + 6bdfc3e commit c5a5bad

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+11150
-954
lines changed

.rubocop_todo.yml

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,57 @@
11
# This configuration was generated by
22
# `rubocop --auto-gen-config`
3-
# on 2024-09-25 08:16:07 UTC using RuboCop version 1.66.1.
3+
# on 2024-09-30 08:46:06 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
77
# versions of RuboCop, may require this file to be generated again.
88

9-
# Offense count: 6
9+
# Offense count: 2
10+
# This cop supports safe autocorrection (--autocorrect).
11+
Lint/RedundantCopDisableDirective:
12+
Exclude:
13+
- '_tools/ruby_h_to_go/spec/ruby_h_to_go/function_definition_spec.rb'
14+
- '_tools/ruby_h_to_go/spec/ruby_header_parser/util_spec.rb'
15+
16+
# Offense count: 8
1017
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
1118
Metrics/AbcSize:
12-
Max: 68
19+
Max: 79
1320

14-
# Offense count: 1
21+
# Offense count: 2
1522
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
1623
# AllowedMethods: refine
1724
Metrics/BlockLength:
18-
Max: 41
19-
20-
# Offense count: 1
21-
# Configuration parameters: CountBlocks, CountModifierForms.
22-
Metrics/BlockNesting:
23-
Max: 4
25+
Max: 48
2426

2527
# Offense count: 2
2628
# Configuration parameters: CountComments, CountAsOne.
2729
Metrics/ClassLength:
2830
Max: 131
2931

30-
# Offense count: 5
32+
# Offense count: 7
3133
# Configuration parameters: AllowedMethods, AllowedPatterns.
3234
Metrics/CyclomaticComplexity:
33-
Max: 17
35+
Max: 15
3436

35-
# Offense count: 12
37+
# Offense count: 15
3638
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
3739
Metrics/MethodLength:
38-
Max: 67
40+
Max: 75
41+
42+
# Offense count: 1
43+
# Configuration parameters: CountComments, CountAsOne.
44+
Metrics/ModuleLength:
45+
Max: 108
3946

4047
# Offense count: 3
4148
# Configuration parameters: AllowedMethods, AllowedPatterns.
4249
Metrics/PerceivedComplexity:
43-
Max: 17
50+
Max: 16
51+
52+
# Offense count: 1
53+
# This cop supports safe autocorrection (--autocorrect).
54+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
55+
# URISchemes: http, https
56+
Layout/LineLength:
57+
Max: 132

_tools/ruby_h_to_go/exe/ruby_h_to_go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ DEFAULT_INCLUDE_PATHS = [
2424
RbConfig::CONFIG["rubyhdrdir"],
2525
].freeze
2626

27-
DEFAULT_DIST_DIR = File.expand_path("../dist", __dir__)
28-
27+
DEFAULT_DIST_DIR = File.expand_path("../../../ruby", __dir__)
2928
DEFAULT_DIST_PREPROCESSED_HEADER_FILE = File.join(Dir.tmpdir, "ruby_preprocessed.h")
3029

3130
opt = OptionParser.new

_tools/ruby_h_to_go/lib/ruby_h_to_go.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
require_relative "ruby_h_to_go/generator_helper"
88
require_relative "ruby_h_to_go/argument_definition"
99
require_relative "ruby_h_to_go/cli"
10+
require_relative "ruby_h_to_go/enum_definition"
1011
require_relative "ruby_h_to_go/function_definition"
1112
require_relative "ruby_h_to_go/struct_definition"
1213
require_relative "ruby_h_to_go/type_definition"

_tools/ruby_h_to_go/lib/ruby_h_to_go/argument_definition.rb

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,23 @@ def go_name
3535

3636
# @return [String]
3737
def go_function_arg
38-
"#{go_name} #{ruby_c_type_to_go_type(type, pointer:, type: :arg)}"
38+
"#{go_name} #{ruby_c_type_to_go_type(type, pointer:, pointer_length: length, pos: :arg)}"
3939
end
4040

4141
# @return [String]
4242
def cast_to_cgo
43-
return "toCArray[#{ruby_c_type_to_go_type(type)}, #{cast_to_cgo_type(type)}](#{go_name})" if pointer == :array
43+
case pointer
44+
when :array
45+
return "toCArray[#{ruby_c_type_to_go_type(type)}, #{cast_to_cgo_type(type)}](#{go_name})"
46+
when :ref_array
47+
return "toCArray[*#{ruby_c_type_to_go_type(type)}, *#{cast_to_cgo_type(type)}](#{go_name})"
48+
when :sref
49+
return go_name if type == "void" && length == 2
50+
51+
return "(#{"*" * length}#{cast_to_cgo_type(type)})(unsafe.Pointer(#{go_name}))"
52+
when :in_ref
53+
return "(*#{cast_to_cgo_type(type)})(#{go_name})"
54+
end
4455

4556
"#{cast_to_cgo_type(type)}(#{go_name})"
4657
end

_tools/ruby_h_to_go/lib/ruby_h_to_go/cli.rb

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,11 @@ def perform
3636
write_type_definitions_to_go_file
3737
write_struct_definitions_to_go_file
3838
write_function_definitions_to_go_file
39+
write_enum_definitions_to_go_file
3940

4041
copy_go_files
41-
42-
# FIXME: Enable after
43-
# remove_unused_imports
44-
# go_fmt
42+
remove_unused_imports
43+
go_fmt
4544
end
4645

4746
private
@@ -56,7 +55,7 @@ def write_type_definitions_to_go_file
5655
RubyHToGo::TypeDefinition.new(definition:)
5756
end
5857

59-
type_definitions.each do |definition|
58+
type_definitions.sort_by(&:name).each do |definition|
6059
definition.write_go_file(dist_dir)
6160
end
6261
end
@@ -66,7 +65,7 @@ def write_struct_definitions_to_go_file
6665
RubyHToGo::StructDefinition.new(definition:)
6766
end
6867

69-
struct_definitions.each do |definition|
68+
struct_definitions.sort_by(&:name).each do |definition|
7069
definition.write_go_file(dist_dir)
7170
end
7271
end
@@ -86,23 +85,33 @@ def write_function_definitions_to_go_file
8685
end
8786
end
8887

89-
function_definitions.each do |definition|
88+
function_definitions.sort_by(&:name).each do |definition|
89+
definition.write_go_file(dist_dir)
90+
end
91+
end
92+
93+
def write_enum_definitions_to_go_file
94+
enum_definitions = parser.extract_enum_definitions.map do |definition|
95+
RubyHToGo::EnumDefinition.new(definition:)
96+
end
97+
98+
enum_definitions.sort_by(&:name).each do |definition|
9099
definition.write_go_file(dist_dir)
91100
end
92101
end
93102

94103
# Clean all generated files in dist/
95104
def clean_generated_files
96-
FileUtils.rm_f(Dir.glob(File.join(dist_dir, "*.go")))
105+
FileUtils.rm_f(Dir.glob(File.join(dist_dir, "*_generated.go")))
97106
end
98107

99108
def copy_go_files
100109
src_dir = File.expand_path("../../../../ruby", __dir__)
101110
return if src_dir == dist_dir
102111

103112
%w[
113+
c_struct.go
104114
c_types.go
105-
types.go
106115
wrapper.go
107116
].each do |file|
108117
FileUtils.cp(File.join(src_dir, file), dist_dir)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# frozen_string_literal: true
2+
3+
module RubyHToGo
4+
# Proxy class for generating go enum
5+
class EnumDefinition
6+
extend Forwardable
7+
8+
def_delegators :@definition, :==, :name, :name=, :values, :values=
9+
10+
include GeneratorHelper
11+
12+
# @param definition [RubyHeaderParser::EnumDefinition]
13+
def initialize(definition:)
14+
@definition = definition
15+
end
16+
17+
# Write definition as go file
18+
# @param [String] dist_dir
19+
def write_go_file(dist_dir)
20+
go_file_path = File.join(dist_dir, "enum_generated.go")
21+
22+
generate_initial_go_file(go_file_path)
23+
24+
File.open(go_file_path, "a") do |f|
25+
f.write(generate_go_content)
26+
end
27+
end
28+
29+
# @return [String]
30+
def generate_go_content
31+
go_type_name = snake_to_camel(name)
32+
33+
go_enum_lines = [
34+
"// #{go_type_name} is a type for passing `C.#{name}` in and out of package",
35+
"type #{go_type_name} int",
36+
"",
37+
"// #{go_type_name} enumeration",
38+
"const (",
39+
]
40+
41+
values.each do |value|
42+
go_enum_lines << "#{value} #{go_type_name} = C.#{value}"
43+
end
44+
45+
go_enum_lines << ")"
46+
go_enum_lines << ""
47+
go_enum_lines << ""
48+
49+
go_enum_lines.join("\n")
50+
end
51+
end
52+
end

_tools/ruby_h_to_go/lib/ruby_h_to_go/function_definition.rb

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -56,37 +56,58 @@ def generate_go_content
5656

5757
casted_go_args = []
5858
char_var_count = args.count { |c_arg| c_arg.type == "char" && c_arg.pointer == :ref }
59+
chars_var_count = args.count { |c_arg| c_arg.type == "char" && c_arg.pointer == :str_array }
5960

6061
before_call_function_lines = []
6162
after_call_function_lines = []
6263

6364
args.each do |c_arg|
64-
if c_arg.type == "char" && c_arg.pointer == :ref
65-
if char_var_count >= 2
66-
char_var_name = "char#{snake_to_camel(c_arg.go_name)}"
67-
clean_var_name = "cleanChar#{c_arg.go_name}"
68-
else
69-
char_var_name = "char"
70-
clean_var_name = "clean"
71-
end
72-
73-
go_function_lines << "#{char_var_name}, #{clean_var_name} := string2Char(#{c_arg.go_name})"
74-
go_function_lines << "defer #{clean_var_name}()"
75-
go_function_lines << ""
76-
77-
casted_go_args << char_var_name.to_s
78-
elsif c_arg.pointer == :ref
79-
if c_arg.type == "void"
80-
casted_go_args << "toCPointer(#{c_arg.go_name})"
65+
case c_arg.pointer
66+
when :ref
67+
case c_arg.type
68+
when "char"
69+
# c_arg is string
70+
if char_var_count >= 2
71+
chars_var_name = "char#{snake_to_camel(c_arg.go_name)}"
72+
clean_var_name = "cleanChar#{c_arg.go_name}"
73+
else
74+
chars_var_name = "char"
75+
clean_var_name = "clean"
76+
end
77+
78+
go_function_lines << "#{chars_var_name}, #{clean_var_name} := string2Char(#{c_arg.go_name})"
79+
go_function_lines << "defer #{clean_var_name}()"
80+
go_function_lines << ""
81+
82+
casted_go_args << chars_var_name.to_s
83+
when "void"
84+
# c_arg is pointer
85+
casted_go_args << c_arg.go_name
8186
else
8287
c_var_name = "c#{snake_to_camel(c_arg.go_name)}"
8388

8489
before_call_function_lines << "var #{c_var_name} #{cast_to_cgo_type(c_arg.type)}"
8590
after_call_function_lines <<
86-
"*#{c_arg.go_name} = #{ruby_c_type_to_go_type(c_arg.type, type: :arg)}(#{c_var_name})"
91+
"*#{c_arg.go_name} = #{ruby_c_type_to_go_type(c_arg.type, pos: :arg)}(#{c_var_name})"
8792

8893
casted_go_args << "&#{c_var_name}"
8994
end
95+
when :function
96+
casted_go_args << "toCFunctionPointer(#{c_arg.go_name})"
97+
when :str_array
98+
if chars_var_count >= 2
99+
chars_var_name = "chars#{snake_to_camel(c_arg.go_name)}"
100+
clean_var_name = "cleanChars#{c_arg.go_name}"
101+
else
102+
chars_var_name = "chars"
103+
clean_var_name = "cleanChars"
104+
end
105+
106+
go_function_lines << "#{chars_var_name}, #{clean_var_name} := strings2Chars(#{c_arg.go_name})"
107+
go_function_lines << "defer #{clean_var_name}()"
108+
go_function_lines << ""
109+
110+
casted_go_args << chars_var_name
90111
else
91112
casted_go_args << c_arg.cast_to_cgo
92113
end
@@ -96,17 +117,11 @@ def generate_go_content
96117
call_c_method << ")"
97118

98119
go_function_lines.push(*before_call_function_lines)
99-
if go_function_typeref == ""
120+
cast_func = typeref.cast_func_for_function_return
121+
if cast_func == ""
100122
go_function_lines << call_c_method
101123
go_function_lines.push(*after_call_function_lines)
102124
else
103-
cast_func =
104-
if go_function_typeref.start_with?("*")
105-
"(#{go_function_typeref})"
106-
else
107-
go_function_typeref
108-
end
109-
110125
go_function_lines << "ret := #{cast_func}(#{call_c_method})"
111126
go_function_lines.push(*after_call_function_lines)
112127
go_function_lines << "return ret"

0 commit comments

Comments
 (0)