rubber-generate 0.0.5
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.
- data/README.md +58 -0
- data/bin/rubber-generate +54 -0
- data/lib/rubber/autord.rb +10 -0
- data/lib/rubber/codegen.rb +131 -0
- data/lib/rubber/codegen/class.rb +79 -0
- data/lib/rubber/codegen/enum.rb +231 -0
- data/lib/rubber/codegen/flags.rb +229 -0
- data/lib/rubber/codegen/float.rb +41 -0
- data/lib/rubber/codegen/function.rb +268 -0
- data/lib/rubber/codegen/gboxed.rb +30 -0
- data/lib/rubber/codegen/gcrefpool.rb +53 -0
- data/lib/rubber/codegen/genum.rb +33 -0
- data/lib/rubber/codegen/gflags.rb +38 -0
- data/lib/rubber/codegen/ginterface.rb +25 -0
- data/lib/rubber/codegen/gobject.rb +42 -0
- data/lib/rubber/codegen/integer.rb +41 -0
- data/lib/rubber/codegen/module.rb +63 -0
- data/lib/rubber/codegen/param.rb +92 -0
- data/lib/rubber/codegen/string.rb +41 -0
- data/lib/rubber/codegen/struct.rb +63 -0
- data/lib/rubber/mkextconf.rb +95 -0
- data/lib/rubber/scanner.rb +419 -0
- data/lib/rubber/struct.rb +52 -0
- data/lib/rubber/types.rb +222 -0
- metadata +85 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
class Class
|
2
|
+
def define_member(name, value=nil)
|
3
|
+
raise "Not a symbol - #{name}" unless name.kind_of?(Symbol)
|
4
|
+
if value.nil?
|
5
|
+
module_eval("attr_accessor #{name.inspect}")
|
6
|
+
else
|
7
|
+
module_eval("attr_writer #{name.inspect};def #{name}(); def self.#{name}(); @#{name}; end; if instance_variables.include?(#{('@'+name.to_s).inspect}) then @#{name} else @#{name} = #{value.inspect}; end; end")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
def define_members(*ids)
|
11
|
+
members = []
|
12
|
+
ids.each do |id|
|
13
|
+
if id.kind_of?(Hash)
|
14
|
+
STDERR.puts("WARNING: Hash passed to define_members has size > 1 in #{caller.join("\n")}\n`#{to_s}.new(...)' will not work as expected (non-predictable member order)") if id.size > 1
|
15
|
+
id.each do |name,value|
|
16
|
+
define_member(name,value)
|
17
|
+
raise "Duplicate definition of member `#{name}'" if members.include?(name.to_s)
|
18
|
+
members.push(name.to_s)
|
19
|
+
end
|
20
|
+
elsif id.kind_of?(Symbol)
|
21
|
+
define_member(id)
|
22
|
+
raise "Duplicate definition of member `#{id}'" if members.include?(id.to_s)
|
23
|
+
members.push(id.to_s)
|
24
|
+
else
|
25
|
+
raise "Neither a Hash nor a Symbol - `#{id}'"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
module_eval <<-EOS
|
29
|
+
def initialize(*ids);
|
30
|
+
members.each_index { |i| __send__((members[i]+'=').intern, i < ids.size ? ids[i] : __send__(members[i].intern)) };
|
31
|
+
if respond_to?(:init)
|
32
|
+
case method(:init).arity
|
33
|
+
when 0
|
34
|
+
__send__(:init) # Avoid errors if init doesn't need args...
|
35
|
+
else
|
36
|
+
__send__(:init,*ids)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
def self.new_from_hash(hash,*args); obj=new(*args); hash.each { |n,v| fn = (n.to_s+'=').intern; if obj.members.include?(n.to_s); obj.__send__(fn, v); else raise ArgumentError, 'Unknown member - '+n.to_s; end }; obj; end
|
41
|
+
def self.members(); #{members.inspect}; end
|
42
|
+
def members(); #{members.inspect}; end
|
43
|
+
def kind_of?(klass); return true if klass == Struct; super(klass); end
|
44
|
+
def to_a(); [#{members.join(', ')}]; end
|
45
|
+
def [](id); id=id.intern if id.kind_of?(String); case id; #{i=-1;members.collect{|name| "when :#{name},#{i+=1}; @#{name};"}} else raise 'Unknown member - '+id.to_s; end; end
|
46
|
+
def []=(id,value); id=id.intern if id.kind_of?(String); case id; #{i=-1;members.collect{|name| "when :#{name},#{i+=1}; @#{name}=value;"}} else raise 'Unknown member - '+id.to_s; end; end
|
47
|
+
def length; #{members.size}; end
|
48
|
+
alias_method(:size, :length)
|
49
|
+
alias_method(:values, :to_a)
|
50
|
+
EOS
|
51
|
+
end
|
52
|
+
end
|
data/lib/rubber/types.rb
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
|
2
|
+
$custom_maps = {}
|
3
|
+
$custom_frees = {}
|
4
|
+
$equivalents = {}
|
5
|
+
module Rubber
|
6
|
+
# Map most GLib types to normal C style ones
|
7
|
+
CMAP = {
|
8
|
+
'ruby'=>'VALUE',
|
9
|
+
'gboolean'=>'bool',
|
10
|
+
'gint'=>'int',
|
11
|
+
'glong'=>'long',
|
12
|
+
'guint'=>'uint',
|
13
|
+
'gchar'=>'char',
|
14
|
+
'gfloat'=>'double', # Ruby only uses doubles?
|
15
|
+
'float'=>'double', # Ruby only uses doubles?
|
16
|
+
'gdouble'=>'double'
|
17
|
+
}
|
18
|
+
class << self
|
19
|
+
def auto_class_map()
|
20
|
+
hsh = {}
|
21
|
+
%w[rb_cObject
|
22
|
+
rb_cArray
|
23
|
+
rb_cBignum
|
24
|
+
rb_cClass
|
25
|
+
rb_cDir
|
26
|
+
rb_cData
|
27
|
+
rb_cFalseClass
|
28
|
+
rb_cFile
|
29
|
+
rb_cFixnum
|
30
|
+
rb_cFloat
|
31
|
+
rb_cHash
|
32
|
+
rb_cInteger
|
33
|
+
rb_cIO
|
34
|
+
rb_cModule
|
35
|
+
rb_cNilClass
|
36
|
+
rb_cNumeric
|
37
|
+
rb_cProc
|
38
|
+
rb_cRange
|
39
|
+
rb_cRegexp
|
40
|
+
rb_cString
|
41
|
+
rb_cSymbol
|
42
|
+
rb_cThread
|
43
|
+
rb_cTime
|
44
|
+
rb_cTrueClass
|
45
|
+
rb_cStruct
|
46
|
+
rb_eException
|
47
|
+
rb_eStandardError
|
48
|
+
rb_eSystemExit
|
49
|
+
rb_eInterrupt
|
50
|
+
rb_eSignal
|
51
|
+
rb_eFatal
|
52
|
+
rb_eArgError
|
53
|
+
rb_eEOFError
|
54
|
+
rb_eIndexError
|
55
|
+
rb_eRangeError
|
56
|
+
rb_eIOError
|
57
|
+
rb_eRuntimeError
|
58
|
+
rb_eSecurityError
|
59
|
+
rb_eSystemCallError
|
60
|
+
rb_eTypeError
|
61
|
+
rb_eZeroDivError
|
62
|
+
rb_eNotImpError
|
63
|
+
rb_eNoMemError
|
64
|
+
rb_eNoMethodError
|
65
|
+
rb_eFloatDomainError
|
66
|
+
rb_eScriptError
|
67
|
+
rb_eNameError
|
68
|
+
rb_eSyntaxError
|
69
|
+
rb_eLoadError].each { |n|
|
70
|
+
hsh[$1]= n.strip if n =~ /rb_[ce]([A-Za-z]+)/
|
71
|
+
}
|
72
|
+
hsh
|
73
|
+
end
|
74
|
+
end
|
75
|
+
RUBY_CLASS_MAP = auto_class_map()
|
76
|
+
|
77
|
+
|
78
|
+
def self.find_class(classname)
|
79
|
+
return nil if classname.nil?
|
80
|
+
return RUBY_CLASS_MAP[classname] if RUBY_CLASS_MAP.has_key?(classname)
|
81
|
+
# Should this be rb_c or just c?
|
82
|
+
# c{NAME} works better... I think...
|
83
|
+
return 'c'+classname
|
84
|
+
end
|
85
|
+
|
86
|
+
RUBY_NATIVE_TYPES = %w|T_NIL T_OBJECT T_CLASS T_MODULE T_FLOAT T_STRING T_REGEXP T_ARRAY T_FIXNUM T_HASH T_STRUCT T_BIGNUM T_FILE T_TRUE T_FALSE T_DATA T_SYMBOL|
|
87
|
+
RUBY_NATIVE_NAMES = %w|Nil Object Class Module Float String Regexp Array Fixnum Hash Struct Bignum File True False Data Symbol|
|
88
|
+
|
89
|
+
def self.native_type?(name)
|
90
|
+
return true if name.nil? or RUBY_NATIVE_TYPES.include?(equivalent_type(name))
|
91
|
+
false
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.count_arr_access(str,name)
|
95
|
+
if name.include?(?[)
|
96
|
+
sc = StringIO.new(name)
|
97
|
+
brac, lev = 0, 0
|
98
|
+
until sc.eof?
|
99
|
+
c = sc.getc
|
100
|
+
if lev == 0 and c == ?[
|
101
|
+
brac += 1
|
102
|
+
end
|
103
|
+
case c
|
104
|
+
when ?[
|
105
|
+
lev += 1
|
106
|
+
when ?]
|
107
|
+
lev -= 1
|
108
|
+
end
|
109
|
+
end
|
110
|
+
brac
|
111
|
+
else
|
112
|
+
0
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.equivalent_type(ctype,name=nil)
|
117
|
+
ctype.gsub!(/ /,'')
|
118
|
+
ctype.strip!
|
119
|
+
ctype.gsub!(/(const|static)/,'')
|
120
|
+
if name
|
121
|
+
brackets = count_arr_access(ctype,name)
|
122
|
+
until brackets == 0
|
123
|
+
ctype = ctype[0..-2] if ctype[-1] == ?*
|
124
|
+
brackets -= 1
|
125
|
+
end
|
126
|
+
end
|
127
|
+
return 'VALUE' if RUBY_NATIVE_TYPES.include?(ctype)
|
128
|
+
ctype= $equivalents[ctype] if $equivalents.has_key?(ctype)
|
129
|
+
return 'VALUE' if RUBY_NATIVE_TYPES.include?(ctype)
|
130
|
+
ctype= CMAP[ctype] if CMAP.has_key?(ctype)
|
131
|
+
ctype
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.explicit_cast(name, ctype, rule)
|
135
|
+
ctype = equivalent_type(ctype, name)
|
136
|
+
rule = equivalent_type(rule)
|
137
|
+
#puts "#{name}:#{ctype}->#{rule}"
|
138
|
+
return name if ctype == rule
|
139
|
+
if $custom_maps.has_key?(ctype)
|
140
|
+
if $custom_maps[ctype].has_key?(rule)
|
141
|
+
return $custom_maps[ctype][rule].gsub(/%%/,"#{name}")
|
142
|
+
end
|
143
|
+
end
|
144
|
+
case ctype
|
145
|
+
when 'VALUE'
|
146
|
+
case rule
|
147
|
+
when 'char*', 'string'
|
148
|
+
"( NIL_P(#{name}) ? NULL : StringValuePtr(#{name}) )"
|
149
|
+
when 'bool'
|
150
|
+
"RTEST(#{name})"
|
151
|
+
when 'int'
|
152
|
+
"NUM2INT(#{name})"
|
153
|
+
when 'uint'
|
154
|
+
"NUM2UINT(#{name})"
|
155
|
+
when 'long'
|
156
|
+
"NUM2LONG(#{name})"
|
157
|
+
when 'double'
|
158
|
+
"NUM2DBL(#{name})"
|
159
|
+
when 'gobject', 'GObject*'
|
160
|
+
"RVAL2GOBJ(#{name})"
|
161
|
+
else
|
162
|
+
raise "Unable to convert #{ctype} to #{rule}"
|
163
|
+
#"#{ctype.gsub(/[* ]/,'_').upcase}_TO_#{rule.upcase}(#{name})"
|
164
|
+
end
|
165
|
+
when 'bool'
|
166
|
+
case rule
|
167
|
+
when 'char*', 'string'
|
168
|
+
"#{name} ? #{"true".inspect} : #{"false".inspect}"
|
169
|
+
when 'VALUE', 'ruby'
|
170
|
+
" ((#{name}) ? Qtrue : Qfalse)"
|
171
|
+
else
|
172
|
+
raise "Unable to convert #{ctype} to #{rule}"
|
173
|
+
#"#{ctype.gsub(/[* ]/,'_').upcase}_TO_#{rule.upcase}(#{name})"
|
174
|
+
end
|
175
|
+
when 'uint'
|
176
|
+
case rule
|
177
|
+
when 'VALUE', 'ruby'
|
178
|
+
" UINT2NUM(#{name})"
|
179
|
+
else
|
180
|
+
raise "Unable to convert #{ctype} to #{rule}"
|
181
|
+
end
|
182
|
+
when 'char*', 'string'
|
183
|
+
case rule
|
184
|
+
when 'VALUE', 'ruby'
|
185
|
+
" rb_str_new2(#{name})"
|
186
|
+
else
|
187
|
+
raise "Unable to convert #{ctype} to #{rule}"
|
188
|
+
end
|
189
|
+
when 'GObject*', 'gobject'
|
190
|
+
case rule
|
191
|
+
when 'VALUE', 'ruby'
|
192
|
+
" GOBJ2RVAL(#{name})"
|
193
|
+
else
|
194
|
+
raise "Unable to convert #{ctype} to #{rule}"
|
195
|
+
end
|
196
|
+
when 'int'
|
197
|
+
case rule
|
198
|
+
when 'VALUE', 'ruby'
|
199
|
+
" INT2NUM(#{name})"
|
200
|
+
else
|
201
|
+
raise "Unable to convert #{ctype} to #{rule}"
|
202
|
+
end
|
203
|
+
when 'long'
|
204
|
+
case rule
|
205
|
+
when 'VALUE', 'ruby'
|
206
|
+
" LONG2NUM(#{name})"
|
207
|
+
else
|
208
|
+
raise "Unable to convert #{ctype} to #{rule}"
|
209
|
+
end
|
210
|
+
when 'double'
|
211
|
+
case rule
|
212
|
+
when 'VALUE', 'ruby'
|
213
|
+
" rb_float_new(#{name})"
|
214
|
+
else
|
215
|
+
raise "Unable to convert #{ctype} to #{rule}"
|
216
|
+
end
|
217
|
+
else
|
218
|
+
raise "Unable to convert #{ctype} to #{rule}"
|
219
|
+
#"#{ctype.gsub(/[* ]/,'_').upcase}_TO_#{rule.upcase}(#{name})"
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubber-generate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 5
|
9
|
+
version: 0.0.5
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Geoff Youngs
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-05-05 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: " rubber-c-binder allows a rubyish means of generating bindings for C libraries,\n including (but not limited to) GObject based libraries.\n\n It allows C code to be written in the context of a ruby style class/method layout\n and eases type checking and conversion between Ruby & C datatypes.\n"
|
22
|
+
email: g@intersect-uk.co.uk
|
23
|
+
executables:
|
24
|
+
- rubber-generate
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- README.md
|
29
|
+
files:
|
30
|
+
- bin/rubber-generate
|
31
|
+
- lib/rubber/autord.rb
|
32
|
+
- lib/rubber/codegen/class.rb
|
33
|
+
- lib/rubber/codegen/enum.rb
|
34
|
+
- lib/rubber/codegen/flags.rb
|
35
|
+
- lib/rubber/codegen/float.rb
|
36
|
+
- lib/rubber/codegen/function.rb
|
37
|
+
- lib/rubber/codegen/gboxed.rb
|
38
|
+
- lib/rubber/codegen/gcrefpool.rb
|
39
|
+
- lib/rubber/codegen/genum.rb
|
40
|
+
- lib/rubber/codegen/gflags.rb
|
41
|
+
- lib/rubber/codegen/ginterface.rb
|
42
|
+
- lib/rubber/codegen/gobject.rb
|
43
|
+
- lib/rubber/codegen/integer.rb
|
44
|
+
- lib/rubber/codegen/module.rb
|
45
|
+
- lib/rubber/codegen/param.rb
|
46
|
+
- lib/rubber/codegen/string.rb
|
47
|
+
- lib/rubber/codegen/struct.rb
|
48
|
+
- lib/rubber/codegen.rb
|
49
|
+
- lib/rubber/mkextconf.rb
|
50
|
+
- lib/rubber/scanner.rb
|
51
|
+
- lib/rubber/struct.rb
|
52
|
+
- lib/rubber/types.rb
|
53
|
+
- README.md
|
54
|
+
has_rdoc: true
|
55
|
+
homepage: http://github.com/geoffyoungs/rubber-generate
|
56
|
+
licenses: []
|
57
|
+
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
version: "0"
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
version: "0"
|
77
|
+
requirements: []
|
78
|
+
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.3.6
|
81
|
+
signing_key:
|
82
|
+
specification_version: 3
|
83
|
+
summary: Template language for generating Ruby bindings for C libraries
|
84
|
+
test_files: []
|
85
|
+
|