Parent

FFI::Generator::Parser

Public Class Methods

new(indent = 2) click to toggle source
    # File lib/generator/parser.rb, line 8
 8:       def initialize(indent = 2)
 9:         @indent = indent
10:         @typedefs = {}
11:         @nested_type = {}
12:         @nested_structure = {}
13:         @ignored = []
14:         @ignore_at_second_pass = []
15:       end

Public Instance Methods

generate(node) click to toggle source
    # File lib/generator/parser.rb, line 16
16:       def generate(node)
17:         result = ""
18:         result = pass(node)
19:         result = pass(node) unless @nested_type.empty?
20:         result
21:       end
ignore(*ignored) click to toggle source
    # File lib/generator/parser.rb, line 22
22:       def ignore(*ignored)
23:         @ignored.concat(ignored)
24:       end
load_config(fn) click to toggle source
    # File lib/generator/parser.rb, line 25
25:       def load_config(fn)
26:         eval(File.read(fn), binding)
27:       end

Private Instance Methods

add_nested_structure(symname, id) click to toggle source
    # File lib/generator/parser.rb, line 42
42:       def add_nested_structure(symname, id)
43:         (@nested_structure[@nested_type[symname]] ||= []) << id
44:       end
add_type(ctype, rtype) click to toggle source
    # File lib/generator/parser.rb, line 39
39:       def add_type(ctype, rtype)
40:         @typedefs[ctype] = rtype
41:       end
callback?(node) click to toggle source
    # File lib/generator/parser.rb, line 66
66:       def callback?(node)
67:         get_attr(node, 'decl') =~ /^p\.f\(/
68:       end
comment(code) click to toggle source
    # File lib/generator/parser.rb, line 97
97:       def comment(code)
98:         code.split(/\n/).map { |line| "# #{line}" }.join("\n") << "\n"
99:       end
constant?(node) click to toggle source
    # File lib/generator/parser.rb, line 48
48:       def constant?(node)
49:         node.name == 'constant'
50:       end
enum?(node) click to toggle source
    # File lib/generator/parser.rb, line 51
51:       def enum?(node)
52:         node.name == 'enum'
53:       end
find_nested_struct(node, id) click to toggle source

Search for nested structures and fix them.

    # File lib/generator/parser.rb, line 84
84:       def find_nested_struct(node, id)
85:         result = ""
86:         nested_node = (node.parent / "class[@id='#{id}']").first
87:         if @nested_structure.has_key?(get_attr(nested_node, 'name'))
88:           @nested_structure[get_attr(nested_node, 'name')].reverse.each do |id|
89:             result << find_nested_struct(nested_node, id)
90:           end
91:         end
92:         result << fix_nested_structure(nested_node) if nested_node
93:       end
fix_nested_structure(node) click to toggle source
    # File lib/generator/parser.rb, line 72
72:       def fix_nested_structure(node)
73:         result = ""
74:         if struct?(node)
75:           s = Struct.new(:node => node, :indent => @indent, :typedefs => @typedefs)
76:           result << (@nested_structure.has_key?(s.symname) ? fixme(s.to_s, NestedStructureNotSupported) : s.to_s)
77:         else
78:           u = Union.new(:node => node, :indent => @indent, :typedefs => @typedefs)
79:           result << (@nested_structure.has_key?(u.symname) ? fixme(u.to_s, NestedStructureNotSupported) : u.to_s)
80:         end
81:         result  
82:       end
fixme(code, message) click to toggle source
    # File lib/generator/parser.rb, line 94
94:       def fixme(code, message)
95:         comment('FIXME: ' + message) << comment(code)
96:       end
function_decl?(node) click to toggle source
    # File lib/generator/parser.rb, line 54
54:       def function_decl?(node)
55:         node.name == 'cdecl' and get_attr(node, 'kind') == 'function'
56:       end
get_attr(node, name) click to toggle source
    # File lib/generator/parser.rb, line 29
29:       def get_attr(node, name)
30:         nodes = (node / "./attributelist/attribute[@name='#{name}']")
31:         nodes.first['value'] if nodes.first
32:       end
get_id(node) click to toggle source
    # File lib/generator/parser.rb, line 33
33:       def get_id(node)
34:         node.id
35:       end
get_verbatim(node) click to toggle source
    # File lib/generator/parser.rb, line 36
36:       def get_verbatim(node)
37:         get_attr(node, 'code')
38:       end
handle_nested_structure(node, symname) click to toggle source
     # File lib/generator/parser.rb, line 113
113:       def handle_nested_structure(node, symname)
114:         if @nested_type[symname]
115:           add_nested_structure(symname, node.attributes['id'])
116:           @ignore_at_second_pass << node.attributes['id']
117:         end
118:         prepend_nested_structures(node, symname)
119:       end
has_nested_structures?(node, symname) click to toggle source
     # File lib/generator/parser.rb, line 100
100:       def has_nested_structures?(node, symname)
101:         @nested_structure[symname] and not @nested_structure[symname].empty?
102:       end
ignore?(name) click to toggle source
     # File lib/generator/parser.rb, line 120
120:       def ignore?(name)
121:         @ignored.any? do |to_be_ignored|
122:           Regexp === to_be_ignored ? to_be_ignored =~ name : to_be_ignored == name
123:         end
124:       end
insert_runtime?(node) click to toggle source
    # File lib/generator/parser.rb, line 45
45:       def insert_runtime?(node)
46:         get_attr(node, 'section') == 'runtime'
47:       end
nested_type?(node) click to toggle source
    # File lib/generator/parser.rb, line 69
69:       def nested_type?(node)
70:         get_attr(node, 'nested')
71:       end
pass(node) click to toggle source
     # File lib/generator/parser.rb, line 125
125:       def pass(node)
126:         result = ""
127:         node.traverse do |node|
128:           unless ignore?(get_attr(node, 'name'))
129:             if constant?(node)
130:               result << Constant.new(:node => node, :indent => @indent).to_s << "\n"
131:             elsif typedef?(node)
132:               typedef = Type.new(:node => node)
133:               add_type(typedef.symname, typedef.full_decl)
134:               if callback?(node)
135:                 cb = Callback.new(:node => node, :indent => @indent, :typedefs => @typedefs).to_s << "\n"
136:                 add_type(typedef.symname, "callback #{typedef.symname}")
137:                 result << cb.to_s
138:               end
139:             elsif enum?(node)
140:               e = Enum.new(:node => node, :indent => @indent)
141:               add_type(e.symname, Generator::TYPES['int'])
142:               result << e.to_s << "\n"
143:             elsif struct?(node)
144:               s = Struct.new(:node => node, :indent => @indent, :typedefs => @typedefs)
145:               add_type(s.symname, "struct #{s.symname}")
146:               unless @ignore_at_second_pass.include? node.attributes['id']
147:                 nested = handle_nested_structure(node, s.symname)
148:                 result << (nested.empty? ? s.to_s : nested << fixme(s.to_s, NestedStructureNotSupported))
149:               end
150:             elsif union?(node)
151:               s = Union.new(:node => node, :indent => @indent, :typedefs => @typedefs)
152:               add_type(s.symname, "union #{s.symname}")
153:               unless @ignore_at_second_pass.include? node.attributes['id']
154:                 nested = handle_nested_structure(node, s.symname)
155:                 result << (nested.empty? ? s.to_s : nested << fixme(s.to_s, NestedStructureNotSupported))
156:               end
157:             elsif function_decl?(node)
158:               result << Function.new(:node => node, :indent => @indent, :typedefs => @typedefs).to_s << "\n"
159:             elsif nested_type?(node)
160:               @nested_type[get_attr(node, 'type')] = get_attr(node, 'nested')
161:             elsif node.name == 'insert' and not insert_runtime?(node) and not node.parent.name == 'class'
162:               result << get_verbatim(node)
163:             end       
164:           end
165:         end
166:         result
167:       end
prepend_nested_structures(node, symname) click to toggle source
     # File lib/generator/parser.rb, line 103
103:       def prepend_nested_structures(node, symname)
104:         result = ""
105:         if has_nested_structures?(node, symname)
106:           @nested_structure[symname].reverse.each do |nested_id|
107:             result << find_nested_struct(node, nested_id)
108:           end
109:           @nested_structure[symname].clear
110:         end
111:         result          
112:       end
struct?(node) click to toggle source
    # File lib/generator/parser.rb, line 57
57:       def struct?(node)
58:         node.name == 'class' and get_attr(node, 'kind') == 'struct'
59:       end
typedef?(node) click to toggle source
    # File lib/generator/parser.rb, line 63
63:       def typedef?(node)
64:         node.name == 'cdecl' and get_attr(node, 'kind') == 'typedef'
65:       end
union?(node) click to toggle source
    # File lib/generator/parser.rb, line 60
60:       def union?(node)
61:         node.name == 'class' and get_attr(node, 'kind') == 'union'
62:       end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.