c2ffi4rb 0.0.0 → 0.0.1

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: 86a593339fb44c53b753ecbae5120b0d3cd67363f8899b8122fa100f800d1fcc
4
- data.tar.gz: c2a2c0ab90ce7e1307d706b268778267237691a56ce71491bfe2503b27b3f8c8
3
+ metadata.gz: 3a7511b48117f836d65991de99d5aeaf1a4dc5f4c9a9b99e4a9577fe415c941a
4
+ data.tar.gz: 3ee454048f080abae9a07ab3a11293d1af7a8f57518d6ae1ae12eaac6fd7d2ab
5
5
  SHA512:
6
- metadata.gz: 42260432b9a7267183c23e4ab79303257e25445c5ea5be46bcf61d7d27b43e8283144741bcf6eb95a9fd66ac7e3094067e68165648fa6fe13594459b588670f4
7
- data.tar.gz: '08281db0ccbaedba8fb39908f343c69dbe348da5e8e49071ded01c382468962b84b308b59c6a57c707586a94dba6b5fb86937d48e0c3a1f37486ae1b52b29bdd'
6
+ metadata.gz: b75a019a77528b7ceac118bc3108991c0cae5aba439ef330a1480fe6dd7390ce04e5780f7263dfab9dd626f98bf754166a9780272277267098e5e1871625d9fe
7
+ data.tar.gz: 3aa7cf6cf49094f75d9ff220c90e66edda3b80092fe96d087c1471b22f71d9d9c5b56a3f5bab914ec0db908222f90c7d0be26f2c9e6eac0a406b806b82f56936
data/README.md CHANGED
@@ -1,8 +1,12 @@
1
1
  # c2ffi4rb
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/c2ffi4rb.svg)](https://badge.fury.io/rb/c2ffi4rb)
4
+ [![test](https://github.com/kojix2/c2ffi4rb/actions/workflows/ci.yml/badge.svg)](https://github.com/kojix2/c2ffi4rb/actions/workflows/ci.yml)
5
+
6
+
3
7
  [c2ffi](https://github.com/rpav/c2ffi) - FFI binding generator - for Ruby
4
8
 
5
- # installation
9
+ ## installation
6
10
 
7
11
  ```sh
8
12
  gem install c2ffi4rb
data/exe/c2ffi4rb CHANGED
@@ -6,7 +6,6 @@
6
6
  ## your build system. But this is how you can use it.
7
7
 
8
8
  require 'optparse'
9
- require 'json'
10
9
  require 'c2ffi4rb'
11
10
 
12
11
  options = {}
@@ -1,120 +1,119 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'json'
4
+
3
5
  module C2FFI4RB
4
6
  class Parser
5
7
  TYPE_TABLE = {
6
- "unsigned-int": :uint,
7
- "unsigned-char": :uchar,
8
- "unsigned-long": :ulong,
9
- "function-pointer": :pointer
10
- }.freeze
8
+ ':unsigned-int' => ':uint',
9
+ ':unsigned-char' => ':uchar',
10
+ ':unsigned-long' => ':ulong',
11
+ ':function-pointer' => ':pointer'
12
+ }
11
13
 
12
14
  def self.parse(arr)
13
15
  Parser.new.parse(arr)
14
16
  end
15
17
 
16
18
  def initialize
17
- @struct_type = {}
19
+ @struct_type = []
18
20
  @toplevels = []
19
21
  @anon_counter = 0
20
22
  end
21
23
 
22
24
  def parse(arr)
23
25
  arr.each do |form|
24
- s = parse_toplevel(form)
25
- @toplevels << s if s
26
+ parse_toplevel(form)
26
27
  end
27
28
 
28
- @toplevels.each do |t|
29
- puts
30
- case t
31
- when String
32
- puts "#{t}"
33
- when Array
34
- t.each do |l|
35
- puts "#{l}"
36
- end
37
- end
38
- end
29
+ puts @toplevels.join("\n\n")
39
30
  end
40
31
 
41
32
  private
42
33
 
43
34
  def parse_toplevel(form)
44
- case form[:tag]
45
- when 'typedef'
46
- type = parse_type(form[:type])
47
-
48
- # I don't think typedef works right with structs, so assign
49
- if @struct_type[type]
50
- name = add_struct(form[:name])
51
- "#{name} = #{type}"
52
- else
53
- "typedef #{type}, :#{form[:name]}"
54
- end
35
+ lines = \
36
+ case form[:tag]
37
+ when 'typedef'
38
+ type = parse_type(form[:type])
39
+
40
+ # I don't think typedef works right with structs, so assign
41
+ if @struct_type.include?(type)
42
+ name = add_struct(form[:name])
43
+ "#{name} = #{type}"
44
+ else
45
+ "typedef #{type}, :#{form[:name]}"
46
+ end
55
47
 
56
- when 'const'
57
- type = parse_type(form[:type])
58
- if type == ':string'
59
- "#{form[:name].upcase} = \"#{form[:value]}\""
60
- else
61
- "#{form[:name].upcase} = #{form[:value]}"
62
- end
48
+ when 'const'
49
+ type = parse_type(form[:type])
50
+ if type == ':string'
51
+ "#{form[:name].upcase} = \"#{form[:value]}\""
52
+ else
53
+ "#{form[:name].upcase} = #{form[:value]}"
54
+ end
63
55
 
64
- when 'extern'
65
- 'attach_variable ' \
66
- ":#{form[:name]}, :#{form[:name]}, #{parse_type(form[:type])}"
56
+ when 'extern'
57
+ 'attach_variable ' \
58
+ ":#{form[:name]}, :#{form[:name]}, #{parse_type(form[:type])}"
67
59
 
68
- when 'function'
69
- s = []
70
- s << "attach_function '#{form[:name]}', ["
71
- form[:parameters].each do |f|
72
- s << " #{parse_type(f[:type])},"
60
+ when 'function'
61
+ l = []
62
+ l << "attach_function '#{form[:name]}', ["
63
+ form[:parameters].each do |f|
64
+ l << " #{parse_type(f[:type])},"
65
+ end
66
+ l << "], #{parse_type(form['return-type'.intern])}"
67
+ # emacs doesn't like :"foo" ---^
68
+ l.join("\n")
69
+
70
+ when 'struct', 'union'
71
+ make_struct(form)
72
+
73
+ when 'enum'
74
+ name = add_enum(form[:name])
75
+ l = []
76
+ l << "enum #{name}, ["
77
+ form[:fields].each do |f|
78
+ l << " :#{f[:name]}, #{f[:value]},"
79
+ end
80
+ l << ']'
81
+ l.join("\n")
73
82
  end
74
- s << "], #{parse_type(form['return-type'.intern])}"
75
- # emacs doesn't like :"foo" ---^
76
83
 
77
- when 'struct', 'union'
78
- name = add_struct(form[:name])
79
- make_struct(form)
80
-
81
- when 'enum'
82
- name = add_enum(form[:name])
83
- s = []
84
- s << "enum #{name}, ["
85
- form[:fields].each do |f|
86
- s << " :#{f[:name]}, #{f[:value]},"
87
- end
88
- s << ']'
89
- end
84
+ @toplevels << lines
85
+ nil
90
86
  end
91
87
 
92
88
  def add_struct(name)
89
+ # Anonymous structs are given a name
93
90
  if name == ''
94
91
  @anon_counter += 1
95
- name = 'Anon_Type_' + @anon_counter.to_s
92
+ name = "Anon_Type_#{@anon_counter}"
96
93
  return name
97
94
  end
98
95
 
96
+ # Do not allow names that start with an underscore
99
97
  name = 'C' + name if name.start_with? '_'
100
98
 
99
+ # Convert snake_case to CamelCase
101
100
  name = name.capitalize.gsub!(/_([a-z])/) { |m| "_#{m[1].upcase}" }
102
- @struct_type[name] = true
101
+
102
+ @struct_type << name unless @struct_type.include? name
103
103
  name
104
104
  end
105
105
 
106
106
  def add_enum(name)
107
+ # Anonymous enums are given a name
107
108
  if name == ''
108
109
  @anon_counter += 1
109
110
  name = ':anon_type_' + @anon_counter.to_s
110
111
  return name
111
112
  end
112
113
 
113
- if name[0] != ':'
114
- ":#{name}"
115
- else
116
- name
117
- end
114
+ # All enums are prefixed with a colon
115
+ name = ":#{name}" unless name.start_with? ':'
116
+ name
118
117
  end
119
118
 
120
119
  def make_struct(form)
@@ -126,19 +125,19 @@ module C2FFI4RB
126
125
  'FFI::Union'
127
126
  end
128
127
 
129
- s = []
130
- s << "class #{name} < #{type}"
128
+ l = []
129
+ l << "class #{name} < #{type}"
131
130
 
132
131
  if form[:fields].length.positive?
133
- s << ' layout \\'
132
+ l << ' layout \\'
134
133
  size = form[:fields].length
135
- sep = ','
136
134
  form[:fields].each_with_index do |f, i|
137
- sep = '' if i >= (size - 1)
138
- s << " :#{f[:name]}, #{parse_type(f[:type])}#{sep}"
135
+ sep = i >= (size - 1) ? '' : ','
136
+ l << " :#{f[:name]}, #{parse_type(f[:type])}#{sep}"
139
137
  end
140
138
  end
141
- s << 'end'
139
+ l << 'end'
140
+ l.join("\n")
142
141
  end
143
142
 
144
143
  def parse_type(form)
@@ -150,8 +149,8 @@ module C2FFI4RB
150
149
  pointee = parse_type(form[:type])
151
150
  if [':char', ':uchar'].include?(pointee)
152
151
  ':string'
153
- elsif @struct_type[pointee]
154
- "#{@struct_type[pointee]}.ptr"
152
+ elsif @struct_type.include?(pointee)
153
+ "#{pointee}.ptr"
155
154
  else
156
155
  ':pointer'
157
156
  end
@@ -1,3 +1,3 @@
1
1
  module C2FFI4RB
2
- VERSION = '0.0.0'
2
+ VERSION = '0.0.1'
3
3
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: c2ffi4rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - kojix2
8
8
  - Ryan Pavlik
9
- autorequire:
9
+ autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2023-09-14 00:00:00.000000000 Z
12
+ date: 2023-09-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -71,7 +71,7 @@ homepage: https://github.com/kojix2/c2ffi4rb
71
71
  licenses:
72
72
  - LGPL-2
73
73
  metadata: {}
74
- post_install_message:
74
+ post_install_message:
75
75
  rdoc_options: []
76
76
  require_paths:
77
77
  - lib
@@ -86,8 +86,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
86
86
  - !ruby/object:Gem::Version
87
87
  version: '0'
88
88
  requirements: []
89
- rubygems_version: 3.4.10
90
- signing_key:
89
+ rubygems_version: 3.4.14
90
+ signing_key:
91
91
  specification_version: 4
92
92
  summary: C2FFI for Ruby-FFI
93
93
  test_files: []