Mercurial > projects > dstep
diff scripts/dstepgen.rb @ 2:9fd439a28ce3
Adapted the scripts for the new bridge + a lot more
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Sun, 05 Jul 2009 17:16:19 +0200 |
parents | 033d260cfc9b |
children | d0162d8ca0f2 |
line wrap: on
line diff
--- a/scripts/dstepgen.rb Thu Jun 18 22:00:13 2009 +0200 +++ b/scripts/dstepgen.rb Sun Jul 05 17:16:19 2009 +0200 @@ -121,6 +121,13 @@ end end +Category = Struct.new(:name, :class) do + def initialize + self.name = "" + self.class = "" + end +end + # This class scans the headers class HeaderScaner CPP = ['/usr/bin/cpp-4.0', '/usr/bin/cpp-3.3', '/usr/bin/cpp3'].find { |x| File.exist?(x) } @@ -136,19 +143,29 @@ @file_content = nil @headers = [] @classes = {} - @informal_protocols = {} + @protocols = {} + @categories = {} + #@informal_protocols = {} @function_pointer_types = {} @do_64bit = false end - def classes + def get_classes @classes end - def protocols - @informal_protocols + def get_protocols + @protocols end + def get_categories + @categories + end + + # def get_informal_protocols + # @informal_protocols + # end + def cftypes (header) re = /typedef\s+(const\s+)?(struct\s*\w+\s*\*\s*)([^\s]+Ref)\s*;/ @cpp_result.scan(re).each do |m| @@ -262,12 +279,24 @@ header.imports = tmp.compact.uniq end - def informal_protocols (header) - self.methods(header) + # def informal_protocols (header) + # methods(header, /^@(interface)\s+(\w+)\s*:?\s*(\w*)\s*(\([^)]+\))?/, @protocols, false) + # end + + def classes (header) + methods(header, /^@(interface)\s+(\w+)\s*:?\s*(\w*)\s*(\<([\w,\s]+)>)?$/, @classes, false) end - def methods (header) - interface_re = /^@(interface|protocol)\s+(\w+)\s*:?\s*(\w*)\s*(\([^)]+\))?/ + def protocols (header) + methods(header, /^@(protocol)\s+(\w+)\s*:?\s*(\w*)\s*(\<([\w,\s]+)>)?(\([^)]+\))?/, @protocols, true) + end + + def categories (header) + methods(header, /^@(interface)\s+(\w+)\s*:?\s*(\w*)\s*(\<([\w,\s]+)>)?(\([^)]+\))/, @categories, false, true) + end + + def methods (header, regex, array, protocol, category = false) + interface_re = regex end_re = /^@end/ body_re = /^[-+]\s*(\([^)]+\))?\s*([^:\s;]+)/ @@ -275,17 +304,28 @@ prop_re = /^@property\s*(\([^)]+\))?\s*([^;]+);$/ current_interface = current_category = nil i = 0 - parent = nil + parent = nil + protocols = nil + cat = nil - @cpp_result.each_line do |line| + @cpp_result.each_line do |line| size = line.size line.strip! if md = interface_re.match(line) parent = nil - current_interface = md[1] == "protocol" ? "NSObject" : md[2] - current_category = md[4].delete("()").strip if md[4] + protocols = nil + current_category = md[6].delete("()").strip if md[6] + current_interface = md[2] unless category + current_interface = current_category if category parent = md[3] unless md[3] == "" + protocols = md[5] if md[5] + + if category + cat = Category.new if category + cat.name = current_category + cat.class = md[2] + end elsif end_re.match(line) current_interface = current_category = nil @@ -310,8 +350,10 @@ typeinfo = VarInfo.new(type, "", "") - @classes[current_interface] ||= {} - methods = (@classes[current_interface].methods ||= []) + array[current_interface] ||= {} unless category + array[cat] ||= {} if category + methods = (array[current_interface].methods ||= []) unless category + methods = (array[cat].methods ||= []) if category methods << MethodInfo.new(typeinfo, getter, false, [], line) unless readonly @@ -377,23 +419,34 @@ args << VarInfo.new("...", "vararg", "") if variadic method = MethodInfo.new(retval, selector, line[0] == ?+, args, data) - if current_category && current_interface == "NSObject" - (@informal_protocols[current_category] ||= []) << method - end + # if protocol && current_category && current_interface == "NSObject" + # (@informal_protocols[current_category] ||= []) << method + # end - @classes[current_interface] ||= {} + array[current_interface] ||= {} unless category + array[cat] ||= {} if category if header.name == current_interface - @classes[current_interface].file = header.name + array[current_interface].file = header.name unless category + array[cat].file = header.name if category else - @classes[current_interface].file ||= header.name + array[current_interface].file ||= header.name unless category + array[cat].file ||= header.name if category end unless parent == current_interface || parent =~ /\s+/ || parent.nil? - @classes[current_interface].parent = parent - end + array[current_interface].parent = parent unless category + array[cat].parent = parent if category + end - (@classes[current_interface].methods ||= []) << method + unless protocols.nil? + protocols.gsub!(/ /, "") + array[current_interface].protocols = protocols unless category + array[cat].protocols = protocols if category + end + + (array[current_interface].methods ||= []) << method unless category + (array[cat].methods ||= []) << method if category end i += size end @@ -493,7 +546,7 @@ end end - def prepare (path) + def prepare (path) @file_content = File.read(path) @file_content.gsub!(%r{(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/)|(//.*)}, ""); @complete_cpp_result, @cpp_result = do_cpp(path, false, true, "") @@ -517,7 +570,10 @@ functions(header) functions(header, true) defines(header) - methods(header) + classes(header) + protocols(header) + #informal_protocols(header) + categories(header) function_pointer_types(header) end end @@ -535,7 +591,10 @@ functions(header) functions(header, true) defines(header) - methods(header) + classes(header) + protocols(header) + #informal_protocols(header) + categories(header) function_pointer_types(header) end end @@ -815,7 +874,7 @@ VERSION = 1.0 - attr_accessor :out_file, :scaner, :code_to_inject + attr_accessor :out_file, :scaner, :code_to_inject, :dependencies_switch def initialize @do_64bit = false @@ -823,12 +882,15 @@ @framework_paths = [] @headers = [] @import_directives = "#import <Foundation/Foundation.h>\n" - @informal_protocols = [] + #@informal_protocols = [] @classes = [] + @protocols = [] + @categories = [] @scaner = HeaderScaner.new @scaner.do_64bit = @do_64bit @umbrella_framework = nil @handled_dependencies = [] + @dependencies_switch = false # link to foundation framework by default @compiler_flags = "-framework Foundation" @@ -841,12 +903,14 @@ def do_64bit= (do_64bit) @do_64bit = do_64bit @scaner.do_64bit = do_64bit - end + end def collect scaner.scan(@frameworks, @headers) - @classes = scaner.classes - @informal_protocols = scaner.protocols + @classes = scaner.get_classes + @protocols = scaner.get_protocols + @categories = scaner.get_categories + #@informal_protocols = scaner.get_informal_protocols end def handle_framework (framework, sub_framework = false, parent_framework = nil) @@ -981,7 +1045,7 @@ def compile_and_execute (code, enable_64bit = false, clean_when_fail = false) compiler_line = "gcc " - src = File.new(unique_tmp_path("src", ".m", "/Users/doob/development/eclipse_workspace/dstep/bindings"), "w") + src = File.new(unique_tmp_path("src", ".m"), "w") src << code src.close @@ -993,8 +1057,8 @@ compiler_line << arch_flag - bin = unique_tmp_path "bin", "", "/Users/doob/development/eclipse_workspace/dstep/bindings" - log = unique_tmp_path "log", ".txt", "/Users/doob/development/eclipse_workspace/dstep/bindings" + bin = unique_tmp_path "bin", "" + log = unique_tmp_path "log", ".txt" line = "#{compiler_line} -o #{bin} #{src.path} #{@compiler_flags} 2>#{log}" @@ -1093,11 +1157,43 @@ types end - def collect_informal_protocols_types (enable_64bit) + def collect_protocols_types (enable_64bit) types = [] - @informal_protocols.each do |name, methods| - methods.each do |method| + @protocols.each do |protocol, value| + value.methods.each do |method| + types << method.stripped_return_type + + method.args.each do |arg| + types << arg.stripped_return_type + end + end + end + + types + end + + # def collect_informal_protocols_types (enable_64bit) + # types = [] + # + # @informal_protocols.each do |name, methods| + # methods.each do |method| + # types << method.stripped_return_type + # + # method.args.each do |arg| + # types << arg.stripped_return_type + # end + # end + # end + # + # types + # end + + def collect_categories_types (enable_64bit) + types = [] + + @categories.each do |category, value| + value.methods.each do |method| types << method.stripped_return_type method.args.each do |arg| @@ -1154,7 +1250,7 @@ i end - def resolve_methods_types (enable_64bit, resolved_types, x) + def resolve_classes_types (enable_64bit, resolved_types, x) i = x @classes.each do |clazz, value| @@ -1174,11 +1270,51 @@ i end - def resolve_informal_protocols_types (enable_64bit, resolved_types, x) + def resolve_protocols_types (enable_64bit, resolved_types, x) i = x - @informal_protocols.each do |name, methods| - methods.each do |method| + @protocols.each do |protocol, value| + value.methods.each do |method| + method.resolved_type = resolved_types[i] unless enable_64bit + method.resolved_type64 = resolved_types[i] if enable_64bit + i += 1 + + method.args.each do |arg| + arg.resolved_type = resolved_types[i] unless enable_64bit + arg.resolved_type64 = resolved_types[i] if enable_64bit + i += 1 + end + end + end + + i + end + + # def resolve_informal_protocols_types (enable_64bit, resolved_types, x) + # i = x + # + # @informal_protocols.each do |name, methods| + # methods.each do |method| + # method.resolved_type = resolved_types[i] unless enable_64bit + # method.resolved_type64 = resolved_types[i] if enable_64bit + # i += 1 + # + # method.args.each do |arg| + # arg.resolved_type = resolved_types[i] unless enable_64bit + # arg.resolved_type64 = resolved_types[i] if enable_64bit + # i += 1 + # end + # end + # end + # + # i + # end + + def resolve_categories_types (enable_64bit, resolved_types, x) + i = x + + @categories.each do |category, value| + value.methods.each do |method| method.resolved_type = resolved_types[i] unless enable_64bit method.resolved_type64 = resolved_types[i] if enable_64bit i += 1 @@ -1211,7 +1347,7 @@ code << @import_directives types = [] - code << @code_to_inject + ";\n" unless @code_to_inject.nil? + code << @code_to_inject + "\n" unless @code_to_inject.nil? @frameworks.each do |framework| framework.headers.each do |header| @@ -1229,7 +1365,9 @@ end types << collect_classes_types(enable_64bit) - types << collect_informal_protocols_types(enable_64bit) + types << collect_protocols_types(enable_64bit) + #types << collect_informal_protocols_types(enable_64bit) + types << collect_categories_types(enable_64bit) code << "int main ()\n{\n" types.flatten! @@ -1257,9 +1395,11 @@ @headers.each do |header| i = resolve_header_types(header, enable_64bit, resolved_types, i) end - - i = resolve_methods_types(enable_64bit, resolved_types, i) - i = resolve_informal_protocols_types(enable_64bit, resolved_types, i) + + i = resolve_classes_types(enable_64bit, resolved_types, i) + i = resolve_protocols_types(enable_64bit, resolved_types, i) + #i = resolve_informal_protocols_types(enable_64bit, resolved_types, i) + i = resolve_categories_types(enable_64bit, resolved_types, i) end def generate_header (xml, header) @@ -1314,7 +1454,7 @@ def generate_classes (xml) @classes.each do |clazz, value| - xml.class :name => clazz, :parent => value.parent, :file => value.file do + xml.class :name => clazz, :parent => value.parent, :protocols => value.protocols, :file => value.file do value.methods.each do |method| xml.method :selector => method.selector, :classMethod => method.class_method?, :variadic => method.variadic? do method.args.each do |arg| @@ -1328,10 +1468,42 @@ end end - def generate_informal_protocols (xml) - @informal_protocols.each do |name, methods| - xml.informalProtocol :name => name do - methods.each do |method| + def generate_protocols (xml) + @protocols.each do |protocol, value| + xml.protocol :name => protocol, :parent => value.parent, :protocols => value.protocols, :file => value.file do + value.methods.each do |method| + xml.method :selector => method.selector, :classMethod => method.class_method?, :variadic => method.variadic? do + method.args.each do |arg| + xml.arg :name => arg.name, :declaredType => arg.return_type, :type => arg.resolved_type, :type64 => arg.resolved_type64, :const => arg.const, :typeModifier => arg.type_modifier + end + + xml.returnValue :declaredType => method.return_type, :type => method.resolved_type, :type64 => method.resolved_type64, :const => method.const, :typeModifier => method.type_modifier + end + end + end + end + end + + # def generate_informal_protocols (xml) + # @informal_protocols.each do |name, methods| + # xml.informalProtocol :name => name do + # methods.each do |method| + # xml.method :selector => method.selector, :classMethod => method.class_method?, :variadic => method.variadic? do + # method.args.each do |arg| + # xml.arg :name => arg.name, :declaredType => arg.return_type, :type => arg.resolved_type, :type64 => arg.resolved_type64, :const => arg.const, :typeModifier => arg.type_modifier + # end + # + # xml.returnValue :declaredType => method.return_type, :type => method.resolved_type, :type64 => method.resolved_type64, :const => method.const, :typeModifier => method.type_modifier + # end + # end + # end + # end + # end + + def generate_categories (xml) + @categories.each do |category, value| + xml.category :name => category.name, :class => category.class, :parent => value.parent, :protocols => value.protocols, :file => value.file do + value.methods.each do |method| xml.method :selector => method.selector, :classMethod => method.class_method?, :variadic => method.variadic? do method.args.each do |arg| xml.arg :name => arg.name, :declaredType => arg.return_type, :type => arg.resolved_type, :type64 => arg.resolved_type64, :const => arg.const, :typeModifier => arg.type_modifier @@ -1368,10 +1540,25 @@ end generate_classes(xml) - generate_informal_protocols(xml) + generate_protocols(xml) + #generate_informal_protocols(xml) + generate_categories(xml) end file.close unless file == STDOUT + end + + def write_dependencies + file = STDOUT if @out_file == nil + file = File.open @out_file, "w" unless @out_file == nil + + @dependencies.each do |dep| + file << dep + "\n" + end + + file.close unless file == STDOUT + + exit 0 end end @@ -1410,10 +1597,14 @@ # dstep_gen.out_dir = opt # end - opts.on("-C", "--code CODE", "Add code") do |opt| + opts.on("-c", "--code CODE", "Add code") do |opt| dstep_gen.code_to_inject = opt end + opts.on("-d", "--dependencies", "Write framework dependencies and exit") do |opt| + dstep_gen.dependencies_switch = true + end + help_msg = "Use the `-h' flag or for help." opts.on("-h", "--help", "Show this message.") do @@ -1434,6 +1625,8 @@ #begin opts.parse!(ARGV) + dstep_gen.write_dependencies if dstep_gen.dependencies_switch + ARGV.each do |header| dstep_gen.add_header(header) end @@ -1448,4 +1641,4 @@ # end end end -end +end \ No newline at end of file