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,30 @@
|
|
1
|
+
require 'rubber/codegen/class'
|
2
|
+
|
3
|
+
module Rubber
|
4
|
+
|
5
|
+
class C_GBoxed < C_Class
|
6
|
+
attr_accessor :gparent_class, :flag_nocopy, :c_type_name
|
7
|
+
def register(io, already_defined=false)
|
8
|
+
io.puts " #{cname} = G_DEF_CLASS(#{superclass}, #{name.inspect}, #{parent.cname});"
|
9
|
+
io.puts " rbgobj_boxed_not_copy_obj(#{superclass});" if self.flag_nocopy
|
10
|
+
|
11
|
+
register_children(io)
|
12
|
+
end
|
13
|
+
def doc_rd(io)
|
14
|
+
id = fullname()
|
15
|
+
id += " < #{gparent_class} " if gparent_class
|
16
|
+
depth = (fullname.gsub(/[^:]/,'').size >> 1)
|
17
|
+
io.puts "=#{'=' * depth} class #{id}"
|
18
|
+
io.puts @doc if @doc
|
19
|
+
contents.each { |f| f.doc_rd(io) }
|
20
|
+
end
|
21
|
+
def default_type
|
22
|
+
c_type_name && (c_type_name + ' *') || 'gpointer'
|
23
|
+
end
|
24
|
+
def pre_func(io, func)
|
25
|
+
io.puts " #{default_type} _self = ((#{default_type})RVAL2BOXED(self, #{superclass}));" if func.text =~ /_self/
|
26
|
+
super(io, func)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end # Rubber
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Rubber
|
2
|
+
|
3
|
+
class C_GCRefPool
|
4
|
+
define_members :name
|
5
|
+
def code(io)
|
6
|
+
io.puts "static void _#{cname}_add(VALUE val)
|
7
|
+
{
|
8
|
+
if (#{cname} == Qnil)
|
9
|
+
{
|
10
|
+
#{cname} = rb_ary_new3(1, val);
|
11
|
+
}
|
12
|
+
else
|
13
|
+
{
|
14
|
+
rb_ary_push(#{cname}, val);
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
static void _#{cname}_del(VALUE val)
|
19
|
+
{
|
20
|
+
if (#{cname} == Qnil)
|
21
|
+
{
|
22
|
+
rb_warn(\"Trying to remove object from empty GC queue #{name}\");
|
23
|
+
return;
|
24
|
+
}
|
25
|
+
rb_ary_delete(#{cname}, val);
|
26
|
+
// If nothing is referenced, don't keep an empty array in the pool...
|
27
|
+
if (RARRAY(#{cname})->len == 0)
|
28
|
+
#{cname} = Qnil;
|
29
|
+
}
|
30
|
+
"
|
31
|
+
end
|
32
|
+
def declare(io)
|
33
|
+
io.puts "static VALUE #{cname} = Qnil;"
|
34
|
+
io.puts "static void _#{cname}_add(VALUE val);"
|
35
|
+
io.puts "static void _#{cname}_del(VALUE val);"
|
36
|
+
io.puts "#define #{name.upcase}_ADD(val) _#{cname}_add(val)"
|
37
|
+
io.puts "#define #{name.upcase}_DEL(val) _#{cname}_del(val)"
|
38
|
+
end
|
39
|
+
include RegisterChildren
|
40
|
+
def default_cname
|
41
|
+
"_gcpool_"+name
|
42
|
+
end
|
43
|
+
def doc_rd(io)
|
44
|
+
# No doc
|
45
|
+
end
|
46
|
+
def fullname()
|
47
|
+
end
|
48
|
+
def register(io, already_defined=false)
|
49
|
+
io.puts "rb_gc_register_address(&#{cname});"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end # Rubber
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rubber/codegen/enum'
|
2
|
+
|
3
|
+
module Rubber
|
4
|
+
|
5
|
+
class C_GEnum < C_Enum
|
6
|
+
define_members :name, :g_type, :prefix, :parent
|
7
|
+
def init()
|
8
|
+
($custom_maps[name] ||= {})["VALUE"] = "GENUM2RVAL(%%, #{g_type})"
|
9
|
+
($custom_maps["VALUE"] ||= {})[name] = "RVAL2GENUM(%%, #{g_type})"
|
10
|
+
end
|
11
|
+
def code(io)
|
12
|
+
end
|
13
|
+
def declare(io)
|
14
|
+
end
|
15
|
+
include RegisterChildren
|
16
|
+
def default_cname
|
17
|
+
"enum"+name
|
18
|
+
end
|
19
|
+
def get_root(); is_root? ? self : parent.get_root; end; def is_root?()
|
20
|
+
not parent.respond_to?(:fullname)
|
21
|
+
end
|
22
|
+
def doc_rd(io)
|
23
|
+
depth = (fullname.gsub(/[^:]/,'').size >> 1)
|
24
|
+
io.puts "=#{'=' * depth} enum #{fullname}"
|
25
|
+
end
|
26
|
+
def register(io, already_defined=false)
|
27
|
+
io.puts " G_DEF_CLASS(#{g_type}, #{name.inspect}, #{get_root.cname});"
|
28
|
+
io.puts " G_DEF_CONSTANTS(#{parent.cname}, #{g_type}, #{prefix.inspect});"
|
29
|
+
# strip = args.first.length - splits.first.length
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end # Rubber
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rubber/codegen/enum'
|
2
|
+
|
3
|
+
module Rubber
|
4
|
+
|
5
|
+
class C_GFlags < C_Enum
|
6
|
+
define_members :name, :g_type, :prefix, :parent
|
7
|
+
def init()
|
8
|
+
($custom_maps[name] ||= {})["VALUE"] = "GFLAGS2RVAL(%%, #{g_type})"
|
9
|
+
($custom_maps["VALUE"] ||= {})[name] = "RVAL2GFLAGS(%%, #{g_type})"
|
10
|
+
gt = g_type.dup
|
11
|
+
gt.sub!("#{$1}_TYPE","#{$1}") if gt =~ /\A([A-Z]+)_TYPE/ # Strip TYPE bit
|
12
|
+
tc = gt.downcase.capitalize.gsub(/_[a-z]/){ |i| i[1..1].upcase}
|
13
|
+
#p tc
|
14
|
+
($custom_maps["VALUE"] ||= {})[tc] = "RVAL2GFLAGS(%%, #{g_type})"
|
15
|
+
end
|
16
|
+
def code(io)
|
17
|
+
end
|
18
|
+
def declare(io)
|
19
|
+
end
|
20
|
+
include RegisterChildren
|
21
|
+
def default_cname
|
22
|
+
"flags"+name
|
23
|
+
end
|
24
|
+
def doc_rd(io)
|
25
|
+
depth = (fullname.gsub(/[^:]/,'').size >> 1)
|
26
|
+
io.puts "=#{'=' * depth} flags #{fullname}"
|
27
|
+
end
|
28
|
+
def get_root(); is_root? ? self : parent.get_root; end; def is_root?()
|
29
|
+
not parent.respond_to?(:fullname)
|
30
|
+
end
|
31
|
+
def register(io, already_defined=false)
|
32
|
+
io.puts " G_DEF_CLASS(#{g_type}, #{name.inspect}, #{get_root.cname});"
|
33
|
+
io.puts " G_DEF_CONSTANTS(#{parent.cname}, #{g_type}, #{prefix.inspect});"
|
34
|
+
# strip = args.first.length - splits.first.length
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end # Rubber
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubber/codegen/class'
|
2
|
+
|
3
|
+
module Rubber
|
4
|
+
|
5
|
+
class C_GInterface < C_Class
|
6
|
+
attr_accessor :gparent_class
|
7
|
+
def register(io, already_defined=false)
|
8
|
+
io.puts " #{cname} = G_DEF_INTERFACE(#{superclass}, #{name.inspect}, #{parent.cname});"
|
9
|
+
register_children(io)
|
10
|
+
end
|
11
|
+
def doc_rd(io)
|
12
|
+
id = fullname()
|
13
|
+
id += " < #{gparent_class} " if gparent_class
|
14
|
+
depth = (fullname.gsub(/[^:]/,'').size >> 1)
|
15
|
+
io.puts "=#{'=' * depth} interface #{id}"
|
16
|
+
io.puts @doc if @doc
|
17
|
+
contents.each { |f| f.doc_rd(io) }
|
18
|
+
end
|
19
|
+
def pre_func(io, func)
|
20
|
+
io.puts " GObject *_self = RVAL2GOBJ(self);" if func.text =~ /_self/
|
21
|
+
super(io, func)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end # Rubber
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rubber/codegen/class'
|
2
|
+
|
3
|
+
module Rubber
|
4
|
+
|
5
|
+
class C_GObject < C_Class
|
6
|
+
attr_accessor :gparent_class, :c_type_name
|
7
|
+
def init()
|
8
|
+
@c_type_name ||= 'GObject' # Default
|
9
|
+
end
|
10
|
+
# def c_type
|
11
|
+
# fullname.sub(/::/,'')+' *'
|
12
|
+
# end
|
13
|
+
def register(io, already_defined=false)
|
14
|
+
if parent.child_names && parent.child_names[name]
|
15
|
+
io.puts " c#{name} = #{cname};"
|
16
|
+
else
|
17
|
+
io.puts " #{cname} = G_DEF_CLASS(#{superclass}, #{name.inspect}, #{parent.cname});"
|
18
|
+
end
|
19
|
+
io.puts @signal_marshals if defined?(@signal_marshals)
|
20
|
+
register_children(io)
|
21
|
+
end
|
22
|
+
def doc_rd(io)
|
23
|
+
id = fullname()
|
24
|
+
id += " < #{gparent_class} " if gparent_class
|
25
|
+
depth = (fullname.gsub(/[^:]/,'').size >> 1)
|
26
|
+
io.puts "=#{'=' * depth} class #{id}"
|
27
|
+
io.puts @doc if @doc
|
28
|
+
contents.each { |f| f.doc_rd(io) }
|
29
|
+
end
|
30
|
+
def feature_signal_marshal(signal,func_name)
|
31
|
+
@signal_marshals ||= ""
|
32
|
+
@signal_marshals << " G_DEF_SIGNAL_FUNC(#{cname}, #{signal.inspect}, #{func_name});\n"
|
33
|
+
end
|
34
|
+
def pre_func(io, func)
|
35
|
+
if func.text =~ /_self/
|
36
|
+
io.puts " #{@c_type_name} *_self = ((#{@c_type_name}*)RVAL2GOBJ(self));"
|
37
|
+
end
|
38
|
+
super(io, func)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end # Rubber
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Rubber
|
2
|
+
|
3
|
+
class C_Integer
|
4
|
+
define_members :name, :number, :parent
|
5
|
+
def code(io)
|
6
|
+
end
|
7
|
+
def declare(io)
|
8
|
+
#io.puts "static VALUE #{cname};"
|
9
|
+
end
|
10
|
+
include RegisterChildren
|
11
|
+
def default_cname
|
12
|
+
#"enum"+name
|
13
|
+
end
|
14
|
+
def doc_rd(io)
|
15
|
+
depth = (fullname.gsub(/[^:]/,'').size >> 1)
|
16
|
+
io.puts "=#{'=' * depth} #{fullname}"
|
17
|
+
end
|
18
|
+
def get_root(); is_root? ? self : parent.get_root; end; def is_root?()
|
19
|
+
not parent.respond_to?(:fullname)
|
20
|
+
end
|
21
|
+
def fullname()
|
22
|
+
if parent and parent.respond_to?(:fullname)
|
23
|
+
"#{parent.fullname}::#{name}"
|
24
|
+
else
|
25
|
+
name
|
26
|
+
end
|
27
|
+
end
|
28
|
+
def get_root(); is_root? ? self : parent.get_root; end;
|
29
|
+
def is_root?()
|
30
|
+
not parent.respond_to?(:fullname)
|
31
|
+
end
|
32
|
+
def register(io, already_defined=false)
|
33
|
+
if parent
|
34
|
+
io.puts " rb_define_const(#{parent.cname}, #{name.inspect}, INT2NUM(#{number}));"
|
35
|
+
else
|
36
|
+
raise "No parent for string constant #{name}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end # Rubber
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Rubber
|
2
|
+
|
3
|
+
class C_Module
|
4
|
+
define_members :name, :classes, :methods, :functions, :constants, :includes, :parent
|
5
|
+
attr_accessor :doc, :child_names
|
6
|
+
def contents()
|
7
|
+
(functions + methods + classes)
|
8
|
+
end
|
9
|
+
def code(io)
|
10
|
+
contents .each { |f| f.code(io) }
|
11
|
+
end
|
12
|
+
def declare(io)
|
13
|
+
io.puts "static VALUE #{cname};" unless external?
|
14
|
+
contents .each { |f| f.declare(io) }
|
15
|
+
end
|
16
|
+
include RegisterChildren
|
17
|
+
def default_cname
|
18
|
+
"m"+name
|
19
|
+
end
|
20
|
+
def doc_rd(io)
|
21
|
+
depth = (fullname.gsub(/[^:]/,'').size >> 1)
|
22
|
+
io.puts "=#{'=' * depth} module #{fullname}"
|
23
|
+
io.puts @doc if @doc
|
24
|
+
contents .each { |f| f.doc_rd(io) }
|
25
|
+
end
|
26
|
+
def get_root(); is_root? ? self : parent.get_root; end
|
27
|
+
def is_root?()
|
28
|
+
not parent.respond_to?(:fullname)
|
29
|
+
end
|
30
|
+
def fullname()
|
31
|
+
if is_root?
|
32
|
+
name
|
33
|
+
else
|
34
|
+
#p parent
|
35
|
+
"#{parent.fullname}::#{name}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
def external? # ie. *defined* externally...
|
39
|
+
cname == 'mGtk' || cname == 'mGdk' || cname == "mGLib"
|
40
|
+
end
|
41
|
+
def add_alias(from, to)
|
42
|
+
(@aliases ||= []) << [from, to]
|
43
|
+
end
|
44
|
+
def register_aliases(io)
|
45
|
+
if @aliases
|
46
|
+
@aliases.each do |from,to|
|
47
|
+
io.puts " rb_define_alias(#{cname},#{from.inspect},#{to.inspect});"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
def register(io, already_defined=false)
|
52
|
+
unless external?
|
53
|
+
if parent and not parent.kind_of?(C_RootModule)
|
54
|
+
io.puts " #{cname} = rb_define_module_under(#{parent.cname}, #{name.inspect});"
|
55
|
+
else
|
56
|
+
io.puts " #{cname} = rb_define_module(#{name.inspect});"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
register_children(io)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end # Rubber
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Rubber
|
2
|
+
|
3
|
+
class C_Param
|
4
|
+
define_members :name, :ctype, :default, :block, :rest, :rtype
|
5
|
+
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|
|
6
|
+
RUBY_NATIVE_NAMES = %w|Nil Object Class Module Float String Regexp Array Fixnum Hash Struct Bignum File True False Data Symbol|
|
7
|
+
|
8
|
+
def initialize(str)
|
9
|
+
r = StringScanner.new(str)
|
10
|
+
@ctype = r.scan(/[a-z_A-Z0-9|]+\s[*]*/) || 'VALUE'
|
11
|
+
@ctype.squeeze!(' ') if @ctype
|
12
|
+
@ctype.strip! if @ctype
|
13
|
+
if RUBY_NATIVE_TYPES.include?(@ctype)
|
14
|
+
@rtype = @ctype
|
15
|
+
@ctype = 'VALUE'
|
16
|
+
elsif (types = @ctype.split(/\|/)).size > 1
|
17
|
+
types.each { |i| i.strip! }
|
18
|
+
if RUBY_NATIVE_TYPES.include?(types.first)
|
19
|
+
@ctype = "VALUE"
|
20
|
+
@rtype = types
|
21
|
+
end
|
22
|
+
end
|
23
|
+
r.skip(/\s*/)
|
24
|
+
@rest = (r.skip(/\*/) and true)
|
25
|
+
@block = (r.skip(/\&/) and true)
|
26
|
+
@name = r.scan(/[A-Za-z0-9_]+/)
|
27
|
+
r.skip(/\s*/)
|
28
|
+
if r.scan(/=(.*)/)
|
29
|
+
@default= r[1].strip
|
30
|
+
end
|
31
|
+
end
|
32
|
+
#include RegisterChildren
|
33
|
+
def cname()
|
34
|
+
if auto_convert?
|
35
|
+
"__v_#{name}"
|
36
|
+
else
|
37
|
+
name
|
38
|
+
end
|
39
|
+
end
|
40
|
+
def auto_convert?
|
41
|
+
ctype and ctype != "VALUE"
|
42
|
+
end
|
43
|
+
def init_value()
|
44
|
+
if @block and not @default
|
45
|
+
"rb_block_proc()"
|
46
|
+
else
|
47
|
+
"Qnil"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
def check_type(io)
|
51
|
+
case @rtype
|
52
|
+
when String
|
53
|
+
io.puts " Check_Type(#{cname}, #{@rtype});"
|
54
|
+
when Array
|
55
|
+
io.puts " if (! (" + @rtype.collect { |type| "(TYPE(#{cname}) == #{type})" }.join(' || ') + ") )"
|
56
|
+
io.puts " rb_raise(rb_eArgError, \"#{name} argument must be one of #{@rtype.collect {|i| RUBY_NATIVE_NAMES[RUBY_NATIVE_TYPES.index(i)]}.join(', ') }\");"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
def declare(io,fn)
|
60
|
+
if auto_convert?
|
61
|
+
io.puts " VALUE #{cname} = #{init_value};" if fn.multi
|
62
|
+
io.puts " #{ctype} #{name}; #{ctype} __orig_#{name};"
|
63
|
+
else
|
64
|
+
io.puts " VALUE #{cname} = #{init_value};" if fn.multi
|
65
|
+
end
|
66
|
+
end
|
67
|
+
def to_str()
|
68
|
+
"#{ctype} #{name} #{default ? ' = ' + default : ''}"
|
69
|
+
end
|
70
|
+
NICE_CNAMES= {'char*'=> 'String', 'long'=>'Integer', 'int'=>'Integer', 'uint'=>'Unsigned Integer', 'ulong'=>'Unsigned Integer', 'bool'=>'Boolean'}
|
71
|
+
def ruby_def()
|
72
|
+
if @rtype.kind_of?(String)
|
73
|
+
type = RUBY_NATIVE_NAMES[RUBY_NATIVE_TYPES.index(rtype)] + ' '
|
74
|
+
elsif @rtype.kind_of?(Array)
|
75
|
+
types = @rtype.dup
|
76
|
+
types.delete('T_NIL') # Don't mention nil option
|
77
|
+
type = types.collect { |rtype| RUBY_NATIVE_NAMES[RUBY_NATIVE_TYPES.index(rtype)] }.join(' or ') + ' '
|
78
|
+
elsif ctype and ctype != 'VALUE'
|
79
|
+
if NICE_CNAMES.has_key?(ctype)
|
80
|
+
type = NICE_CNAMES[ctype]
|
81
|
+
else
|
82
|
+
type = ctype
|
83
|
+
end
|
84
|
+
type += ' '
|
85
|
+
else
|
86
|
+
type = ''
|
87
|
+
end
|
88
|
+
"#{type}#{name}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end # Rubber
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Rubber
|
2
|
+
|
3
|
+
class C_String
|
4
|
+
define_members :name, :string, :parent
|
5
|
+
def code(io)
|
6
|
+
end
|
7
|
+
def declare(io)
|
8
|
+
#io.puts "static VALUE #{cname};"
|
9
|
+
end
|
10
|
+
include RegisterChildren
|
11
|
+
def default_cname
|
12
|
+
#"enum"+name
|
13
|
+
end
|
14
|
+
def doc_rd(io)
|
15
|
+
depth = (fullname.gsub(/[^:]/,'').size >> 1)
|
16
|
+
io.puts "=#{'=' * depth} #{fullname}"
|
17
|
+
end
|
18
|
+
def get_root(); is_root? ? self : parent.get_root; end; def is_root?()
|
19
|
+
not parent.respond_to?(:fullname)
|
20
|
+
end
|
21
|
+
def fullname()
|
22
|
+
if parent and parent.respond_to?(:fullname)
|
23
|
+
"#{parent.fullname}::#{name}"
|
24
|
+
else
|
25
|
+
name
|
26
|
+
end
|
27
|
+
end
|
28
|
+
def get_root(); is_root? ? self : parent.get_root; end;
|
29
|
+
def is_root?()
|
30
|
+
not parent.respond_to?(:fullname)
|
31
|
+
end
|
32
|
+
def register(io, already_defined=false)
|
33
|
+
if parent
|
34
|
+
io.puts " rb_define_const(#{parent.cname}, #{name.inspect}, rb_str_new2(#{string}));"
|
35
|
+
else
|
36
|
+
raise "No parent for string constant #{name}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end # Rubber
|