rubber-generate 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|